diff options
author | Oliver Bolte <obo@openoffice.org> | 2004-06-04 13:02:26 +0000 |
---|---|---|
committer | Oliver Bolte <obo@openoffice.org> | 2004-06-04 13:02:26 +0000 |
commit | 203acff619a92c405c36fdd607ec8f8734b0e866 (patch) | |
tree | 012892c13f182032d19e5ef5177e29fb865d0aa7 /sc/source/filter/excel/xipivot.cxx | |
parent | 1d4cf8b43290134a9a7e67aa57cacfc4384b80da (diff) |
INTEGRATION: CWS fieldoptions (1.1.2); FILE ADDED
2004/05/17 15:00:19 dr 1.1.2.9: #i23447# reimpl of pivot table export, step 5: sort info, minor adjustments
2004/05/14 16:21:37 dr 1.1.2.8: #i23447# reimpl of pivot table export, step 3: general field options, data field options
2004/05/13 17:10:24 dr 1.1.2.7: #i23447# reimpl of pivot table export, step 2: raw structure of pivot tables
2004/05/13 12:04:04 dr 1.1.2.6: #i23447# reimpl of pivot table export, step 1: pivot cache
2004/05/12 19:49:23 dr 1.1.2.5: #i23447# import of SXDATETIME, SXBOOLEAN, SXERROR, SXEMPTY cache items
2004/05/12 14:03:19 dr 1.1.2.4: #i23447# handling of skipped object
2004/05/12 13:20:04 dr 1.1.2.3: #i23447# sheet name and ScAddress handling
2004/05/12 12:08:57 dr 1.1.2.2: #i23447# import of field layout options
2004/05/12 11:41:04 dr 1.1.2.1: #i23447# reimpl of pivot table import completed
Diffstat (limited to 'sc/source/filter/excel/xipivot.cxx')
-rw-r--r-- | sc/source/filter/excel/xipivot.cxx | 917 |
1 files changed, 917 insertions, 0 deletions
diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx new file mode 100644 index 000000000000..a2516288a645 --- /dev/null +++ b/sc/source/filter/excel/xipivot.cxx @@ -0,0 +1,917 @@ +/************************************************************************* + * + * $RCSfile: xipivot.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: obo $ $Date: 2004-06-04 14:02:26 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef SC_XIPIVOT_HXX +#include "xipivot.hxx" +#endif + +#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDSORTINFO_HPP_ +#include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp> +#endif +#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDAUTOSHOWINFO_HPP_ +#include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp> +#endif +#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDLAYOUTINFO_HPP_ +#include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp> +#endif +#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDREFERENCE_HPP_ +#include <com/sun/star/sheet/DataPilotFieldReference.hpp> +#endif + +#ifndef _DATETIME_HXX +#include <tools/datetime.hxx> +#endif +#ifndef _ZFORMAT_HXX +#include <svtools/zformat.hxx> +#endif + +#ifndef SC_DOCUMENT_HXX +#include "document.hxx" +#endif +#ifndef SC_DPSAVE_HXX +#include "dpsave.hxx" +#endif +#ifndef SC_DPOBJECT_HXX +#include "dpobject.hxx" +#endif +#ifndef SC_DPSHTTAB_HXX +#include "dpshttab.hxx" +#endif + +#ifndef SC_XLTRACER_HXX +#include "xltracer.hxx" +#endif +#ifndef SC_XISTREAM_HXX +#include "xistream.hxx" +#endif +#ifndef SC_XILINK_HXX +#include "xilink.hxx" +#endif +#ifndef SC_XIESCHER_HXX +#include "xiescher.hxx" +#endif + +#include "root.hxx" + +using ::rtl::OUString; +using ::com::sun::star::sheet::DataPilotFieldOrientation; +using ::com::sun::star::sheet::DataPilotFieldOrientation_DATA; +using ::com::sun::star::sheet::DataPilotFieldSortInfo; +using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo; +using ::com::sun::star::sheet::DataPilotFieldLayoutInfo; +using ::com::sun::star::sheet::DataPilotFieldReference; + +// ============================================================================ +// Pivot cache +// ============================================================================ + +XclImpPCItem::XclImpPCItem( XclImpStream& rStrm, sal_uInt16 nRecId ) +{ + switch( nRecId ) + { + case EXC_ID_SXDOUBLE: ReadSxdouble( rStrm ); break; + case EXC_ID_SXBOOLEAN: ReadSxboolean( rStrm ); break; + case EXC_ID_SXERROR: ReadSxerror( rStrm ); break; + case EXC_ID_SXSTRING: ReadSxstring( rStrm ); break; + case EXC_ID_SXDATETIME: ReadSxdatetime( rStrm ); break; + case EXC_ID_SXEMPTY: ReadSxempty( rStrm ); break; + default: DBG_ERRORFILE( "XclImpPCItem::XclImpPCItem - unknown record id" ); + } +} + +void XclImpPCItem::ReadSxdouble( XclImpStream& rStrm ) +{ + DBG_ASSERT( rStrm.GetRecSize() == 8, "XclImpPCItem::ReadSxdouble - wrong record size" ); + SetValue( rStrm.ReadDouble() ); +} + +void XclImpPCItem::ReadSxboolean( XclImpStream& rStrm ) +{ + DBG_ASSERT( rStrm.GetRecSize() == 2, "XclImpPCItem::ReadSxboolean - wrong record size" ); + SetBool( rStrm.ReaduInt16() != 0 ); +} + +void XclImpPCItem::ReadSxerror( XclImpStream& rStrm ) +{ + DBG_ASSERT( rStrm.GetRecSize() == 2, "XclImpPCItem::ReadSxerror - wrong record size" ); + SetError( rStrm.ReaduInt16() ); +} + +void XclImpPCItem::ReadSxstring( XclImpStream& rStrm ) +{ + DBG_ASSERT( rStrm.GetRecSize() >= 3, "XclImpPCItem::ReadSxstring - wrong record size" ); + SetText( rStrm.ReadUniString() ); +} + +void XclImpPCItem::ReadSxdatetime( XclImpStream& rStrm ) +{ + DBG_ASSERT( rStrm.GetRecSize() == 8, "XclImpPCItem::ReadSxdatetime - wrong record size" ); + + sal_uInt16 nYear, nMonth; + sal_uInt8 nDay, nHour, nMin, nSec; + rStrm >> nYear >> nMonth >> nDay >> nHour >> nMin >> nSec; + + DateTime aNullDate( *rStrm.GetRoot().GetFormatter().GetNullDate() ); + DateTime aDate( Date( nDay, nMonth, nYear ), Time( nHour, nMin, nSec ) ); + SetDate( aDate - aNullDate ); +} + +void XclImpPCItem::ReadSxempty( XclImpStream& rStrm ) +{ + DBG_ASSERT( rStrm.GetRecSize() == 0, "XclImpPCItem::ReadSxempty - wrong record size" ); + SetEmpty(); +} + +// ============================================================================ + +XclImpPCField::XclImpPCField( const String& rName, bool bPostponeItems ) : + maName( rName ), + mbPostponeItems( bPostponeItems ) +{ +} + +XclImpPCField::~XclImpPCField() +{ +} + +const XclImpPCItem* XclImpPCField::GetItem( sal_uInt16 nItemIdx ) const +{ + return maItemList.GetObject( nItemIdx ); +} + +void XclImpPCField::ReadItem( XclImpStream& rStrm, sal_uInt16 nRecId ) +{ + maItemList.Append( new XclImpPCItem( rStrm, nRecId ) ); +} + +// ============================================================================ + +XclImpPivotCache::XclImpPivotCache( const XclImpRoot& rRoot, sal_uInt16 nStrmId ) : + XclImpRoot( rRoot ), + mnSrcType( EXC_SXVS_UNKNOWN ) +{ + if( SvStorage* pSt = mpRD->pPivotCacheStorage ) + { + SvStorageStreamRef pStIn = pSt->OpenStream( ScfTools::GetHexStr( nStrmId ), STREAM_STD_READ ); + if( pStIn.Is() ) + { + XclImpStream aStrm( *pStIn, GetRoot() ); + ReadPivotCacheStream( aStrm ); + } + } +} + +XclImpPivotCache::~XclImpPivotCache() +{ +} + +// data access ---------------------------------------------------------------- + +const String& XclImpPivotCache::GetFieldName( sal_uInt16 nFieldIdx ) const +{ + if( const XclImpPCField* pField = maFieldList.GetObject( nFieldIdx ) ) + return pField->GetFieldName(); + return EMPTY_STRING; +} + +const XclImpPCItem* XclImpPivotCache::GetItem( sal_uInt16 nFieldIdx, sal_uInt16 nItemIdx ) const +{ + if( const XclImpPCField* pField = maFieldList.GetObject( nFieldIdx ) ) + return pField->GetItem( nItemIdx ); + return 0; +} + +// records -------------------------------------------------------------------- + +void XclImpPivotCache::ReadDconref( XclImpStream& rStrm ) +{ + // read DCONREF only once, there may be others in another context + if( maTabName.Len() ) + return; + + sal_uInt16 nStartRow, nEndRow; + sal_uInt8 nStartCol, nEndCol; + rStrm >> nStartRow >> nEndRow >> nStartCol >> nEndCol; + String aEncUrl( rStrm.ReadUniString() ); + + XclImpUrlHelper::DecodeUrl( maUrl, maTabName, mbSelf, GetRoot(), aEncUrl ); + if( !maTabName.Len() ) + { + maTabName = maUrl; + maUrl.Erase(); + } + + // Sheet index will be found later in XclImpPivotTable::Apply() (sheet may not exist yet). + // Do not convert maTabName to Calc sheet name -> original name is used to find the sheet. + maSrcRange.aStart.Set( static_cast< SCCOL >( nStartCol ), static_cast< SCROW >( nStartRow ), 0 ); + maSrcRange.aEnd.Set( static_cast< SCCOL >( nEndCol ), static_cast< SCROW >( nEndRow ), 0 ); + CheckCellRange( maSrcRange ); +} + +void XclImpPivotCache::ReadSxvs( XclImpStream& rStrm ) +{ + rStrm >> mnSrcType; + GetTracer().TracePivotDataSource( mnSrcType == EXC_SXVS_EXTERN ); +} + +// private -------------------------------------------------------------------- + +void XclImpPivotCache::ReadPivotCacheStream( XclImpStream& rStrm ) +{ + XclImpPCField* pCurrField = 0; // Current field for new items. + bool bExistPostponed = false; // true = Any field with postponed items. + bool bReadPostponed = false; // true = Read now into postponed fields. + bool bLoop = true; // true = Continue loop. + + while( bLoop && rStrm.StartNextRecord() ) + { + bool bLastWasItem = false; // true = Last record was item data. + + switch( rStrm.GetRecId() ) + { + case EXC_ID_EOF: + bLoop = false; + break; + + case EXC_ID_SXFIELD: + { + sal_uInt16 nFlags; + rStrm >> nFlags; + rStrm.Ignore( 12 ); + if( rStrm.GetRecLeft() >= 3 ) + { + bool bPostponeItems = ::get_flag( nFlags, EXC_SXFIELD_POSTPONE ); + pCurrField = new XclImpPCField( rStrm.ReadUniString(), bPostponeItems ); + maFieldList.Append( pCurrField ); + bExistPostponed |= bPostponeItems; + } + } + break; + + case EXC_ID_SXIDARRAY: + // Items of postponed fields start now. + bReadPostponed = bExistPostponed; + if( bReadPostponed ) + { + // Find the first postponed field. + pCurrField = maFieldList.First(); + while( pCurrField && !pCurrField->HasPostponedItems() ) + pCurrField = maFieldList.Next(); + } + break; + + case EXC_ID_SXDOUBLE: + case EXC_ID_SXBOOLEAN: + case EXC_ID_SXERROR: + case EXC_ID_SXSTRING: + case EXC_ID_SXDATETIME: + case EXC_ID_SXEMPTY: + if( pCurrField ) + pCurrField->ReadItem( rStrm, rStrm.GetRecId() ); + bLastWasItem = true; + break; + } + + if( bReadPostponed && bLastWasItem ) + { + // Find the next postponed field. + pCurrField = maFieldList.Next(); + while( pCurrField && !pCurrField->HasPostponedItems() ) + pCurrField = maFieldList.Next(); + } + } +} + +// ============================================================================ +// Pivot table +// ============================================================================ + +XclImpPTItem::XclImpPTItem( sal_uInt16 nFieldCacheIdx ) : + mnFieldCacheIdx( nFieldCacheIdx ) +{ +} + +const String* XclImpPTItem::GetItemName( const XclImpPivotCache* pCache ) const +{ + if( !maItemInfo.mbUseCache ) + return &maItemInfo.maName; + if( pCache ) + if( const XclImpPCItem* pCacheItem = pCache->GetItem( mnFieldCacheIdx, maItemInfo.mnCacheIdx ) ) + //! TODO: use XclImpPCItem::ConvertToString(), if all conversions are available + return pCacheItem->IsEmpty() ? &EMPTY_STRING : pCacheItem->GetText(); + return 0; +} + +void XclImpPTItem::ReadSxvi( XclImpStream& rStrm ) +{ + rStrm >> maItemInfo; +} + +void XclImpPTItem::ApplyItem( ScDPSaveDimension& rSaveDim, const XclImpPivotCache* pCache ) const +{ + if( const String* pItemName = GetItemName( pCache ) ) + { + ScDPSaveMember& rMember = *rSaveDim.GetMemberByName( *pItemName ); + rMember.SetIsVisible( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN ) ); + rMember.SetShowDetails( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL ) ); + } +} + +// ============================================================================ + +XclImpPTField::XclImpPTField( const XclImpPivotTable& rPTable, sal_uInt16 nCacheIdx ) : + mrPTable( rPTable ) +{ + maFieldInfo.mnCacheIdx = nCacheIdx; +} + +// general field/item access -------------------------------------------------- + +const String& XclImpPTField::GetFieldName() const +{ + if( const XclImpPivotCache* pCache = mrPTable.GetPivotCache() ) + return pCache->GetFieldName( maFieldInfo.mnCacheIdx ); + return EMPTY_STRING; +} + +const XclImpPTItem* XclImpPTField::GetItem( sal_uInt16 nItemIdx ) const +{ + return maItemList.GetObject( nItemIdx ); +} + +const String* XclImpPTField::GetItemName( sal_uInt16 nItemIdx ) const +{ + if( const XclImpPTItem* pItem = GetItem( nItemIdx ) ) + return pItem->GetItemName( mrPTable.GetPivotCache() ); + return 0; +} + +void XclImpPTField::SetAxes( sal_uInt16 nAxes ) +{ + maFieldInfo.mnAxes = nAxes; +} + +// records -------------------------------------------------------------------- + +void XclImpPTField::ReadSxvd( XclImpStream& rStrm ) +{ + rStrm >> maFieldInfo; +} + +void XclImpPTField::ReadSxvdex( XclImpStream& rStrm ) +{ + rStrm >> maFieldExtInfo; +} + +void XclImpPTField::ReadSxvi( XclImpStream& rStrm ) +{ + XclImpPTItem* pItem = new XclImpPTItem( maFieldInfo.mnCacheIdx ); + maItemList.Append( pItem ); + pItem->ReadSxvi( rStrm ); +} + +// row/column fields ---------------------------------------------------------- + +void XclImpPTField::ApplyRowColField( ScDPSaveData& rSaveData ) const +{ + DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_RC_MASK, "XclImpPTField::ApplyRowColField - no row/column field" ); + if( maFieldInfo.mnCacheIdx == EXC_SXIVD_DATA ) + { + // special data orientation field + rSaveData.GetDataLayoutDimension()->SetOrientation( maFieldInfo.GetApiOrient() ); + } + else + { + const String& rFieldName = GetFieldName(); + if( rFieldName.Len() ) + { + ScDPSaveDimension& rSaveDim = *rSaveData.GetNewDimensionByName( rFieldName ); + ApplyRCPField( rSaveDim ); + } + } +} + +// page fields ---------------------------------------------------------------- + +void XclImpPTField::SetPageFieldInfo( const XclPTPageFieldInfo& rPageInfo ) +{ + maPageInfo = rPageInfo; +} + +void XclImpPTField::ApplyPageField( ScDPSaveData& rSaveData ) const +{ + DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_PAGE, "XclImpPTField::ApplyPageField - no page field" ); + const String& rFieldName = GetFieldName(); + if( rFieldName.Len() ) + { + ScDPSaveDimension& rSaveDim = *rSaveData.GetNewDimensionByName( rFieldName ); + ApplyRCPField( rSaveDim ); + rSaveDim.SetCurrentPage( GetItemName( maPageInfo.mnSelItem ) ); + } +} + +// data fields ---------------------------------------------------------------- + +bool XclImpPTField::HasDataFieldInfo() const +{ + return !maDataInfoList.empty(); +} + +void XclImpPTField::AddDataFieldInfo( const XclPTDataFieldInfo& rDataInfo ) +{ + DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_DATA, "XclImpPTField::AddDataFieldInfo - no data field" ); + maDataInfoList.push_back( rDataInfo ); +} + +void XclImpPTField::ApplyDataField( ScDPSaveData& rSaveData ) const +{ + DBG_ASSERT( maFieldInfo.mnAxes & EXC_SXVD_AXIS_DATA, "XclImpPTField::ApplyDataField - no data field" ); + DBG_ASSERT( !maDataInfoList.empty(), "XclImpPTField::ApplyDataField - no data field info" ); + if( !maDataInfoList.empty() ) + { + const String& rFieldName = GetFieldName(); + if( rFieldName.Len() ) + { + XclPTDataFieldInfoList::const_iterator aIt = maDataInfoList.begin(), aEnd = maDataInfoList.end(); + + ScDPSaveDimension& rSaveDim = *rSaveData.GetNewDimensionByName( rFieldName ); + ApplyDataField( rSaveDim, *aIt ); + + // multiple data fields -> clone dimension + for( ++aIt; aIt != aEnd; ++aIt ) + { + ScDPSaveDimension& rDupDim = rSaveData.DuplicateDimension( rSaveDim ); + ApplyDataFieldInfo( rDupDim, *aIt ); + } + } + } +} + +// private -------------------------------------------------------------------- + +void XclImpPTField::ApplyRCPField( ScDPSaveDimension& rSaveDim ) const +{ + // orientation + rSaveDim.SetOrientation( maFieldInfo.GetApiOrient() ); + + // general field info + ApplyFieldInfo( rSaveDim ); + + // visible name + if( maFieldInfo.maVisName.Len() ) + rSaveDim.SetLayoutName( &maFieldInfo.maVisName ); + + // subtotal function(s) + XclPTSubtotalVec aSubtotalVec; + maFieldInfo.GetSubtotals( aSubtotalVec ); + if( !aSubtotalVec.empty() ) + rSaveDim.SetSubTotals( static_cast< long >( aSubtotalVec.size() ), &aSubtotalVec[ 0 ] ); + + // sorting + DataPilotFieldSortInfo aSortInfo; + aSortInfo.Field = mrPTable.GetDataFieldName( maFieldExtInfo.mnSortField ); + aSortInfo.IsAscending = ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SORT_ASC ); + aSortInfo.Mode = maFieldExtInfo.GetApiSortMode(); + rSaveDim.SetSortInfo( &aSortInfo ); + + // auto show + DataPilotFieldAutoShowInfo aShowInfo; + aShowInfo.IsEnabled = ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_AUTOSHOW ); + aShowInfo.ShowItemsMode = maFieldExtInfo.GetApiAutoShowMode(); + aShowInfo.ItemCount = maFieldExtInfo.GetApiAutoShowCount(); + aShowInfo.DataField = mrPTable.GetDataFieldName( maFieldExtInfo.mnShowField ); + rSaveDim.SetAutoShowInfo( &aShowInfo ); + + // layout + DataPilotFieldLayoutInfo aLayoutInfo; + aLayoutInfo.LayoutMode = maFieldExtInfo.GetApiLayoutMode(); + aLayoutInfo.AddEmptyLines = ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_LAYOUT_BLANK ); + rSaveDim.SetLayoutInfo( &aLayoutInfo ); +} + +void XclImpPTField::ApplyDataField( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const +{ + // orientation + rSaveDim.SetOrientation( DataPilotFieldOrientation_DATA ); + // general field info + ApplyFieldInfo( rSaveDim ); + // extended data field info + ApplyDataFieldInfo( rSaveDim, rDataInfo ); +} + +void XclImpPTField::ApplyFieldInfo( ScDPSaveDimension& rSaveDim ) const +{ + rSaveDim.SetShowEmpty( ::get_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL ) ); + ApplyItems( rSaveDim ); +} + +void XclImpPTField::ApplyDataFieldInfo( ScDPSaveDimension& rSaveDim, const XclPTDataFieldInfo& rDataInfo ) const +{ + // visible name + if( rDataInfo.maVisName.Len() ) + rSaveDim.SetLayoutName( &rDataInfo.maVisName ); + + // aggregation function + rSaveDim.SetFunction( rDataInfo.GetApiAggFunc() ); + + // result field reference + sal_Int32 nRefType = rDataInfo.GetApiRefType(); + if( nRefType != ::com::sun::star::sheet::DataPilotFieldReferenceType::NONE ) + { + DataPilotFieldReference aFieldRef; + aFieldRef.ReferenceType = nRefType; + + if( const XclImpPTField* pRefField = mrPTable.GetField( rDataInfo.mnRefField ) ) + { + aFieldRef.ReferenceField = pRefField->GetFieldName(); + aFieldRef.ReferenceItemType = rDataInfo.GetApiRefItemType(); + if( aFieldRef.ReferenceItemType == ::com::sun::star::sheet::DataPilotFieldReferenceItemType::NAMED ) + if( const String* pRefItemName = pRefField->GetItemName( rDataInfo.mnRefItem ) ) + aFieldRef.ReferenceItemName = *pRefItemName; + } + + rSaveDim.SetReferenceValue( &aFieldRef ); + } +} + +void XclImpPTField::ApplyItems( ScDPSaveDimension& rSaveDim ) const +{ + const XclImpPivotCache* pCache = mrPTable.GetPivotCache(); + for( const XclImpPTItem* pItem = maItemList.First(); pItem; pItem = maItemList.Next() ) + pItem->ApplyItem( rSaveDim, pCache ); +} + +// ============================================================================ + +XclImpPivotTable::XclImpPivotTable( const XclImpRoot& rRoot ) : + XclImpRoot( rRoot ), + mpPCache( 0 ), + + maDataOrientField( *this, EXC_SXIVD_DATA ), + mpCurrField( 0 ) +{ +} + +XclImpPivotTable::~XclImpPivotTable() +{ +} + +// cache/field access, misc. -------------------------------------------------- + +const XclImpPTField* XclImpPivotTable::GetField( sal_uInt16 nFieldIdx ) const +{ + return (nFieldIdx == EXC_SXIVD_DATA) ? &maDataOrientField : maFieldList.GetObject( nFieldIdx ); +} + +XclImpPTField* XclImpPivotTable::GetFieldAcc( sal_uInt16 nFieldIdx ) +{ + return maFieldList.GetObject( nFieldIdx ); // do not return maDataOrientField +} + +const String& XclImpPivotTable::GetFieldName( sal_uInt16 nFieldIdx ) const +{ + if( const XclImpPTField* pField = GetField( nFieldIdx ) ) + return pField->GetFieldName(); + return EMPTY_STRING; +} + +const XclImpPTField* XclImpPivotTable::GetDataField( sal_uInt16 nDataFieldIdx ) const +{ + if( nDataFieldIdx < maOrigDataFields.size() ) + return GetField( maOrigDataFields[ nDataFieldIdx ] ); + return 0; +} + +const String& XclImpPivotTable::GetDataFieldName( sal_uInt16 nDataFieldIdx ) const +{ + if( const XclImpPTField* pField = GetDataField( nDataFieldIdx ) ) + return pField->GetFieldName(); + return EMPTY_STRING; +} + +// records -------------------------------------------------------------------- + +void XclImpPivotTable::ReadSxview( XclImpStream& rStrm ) +{ + rStrm >> maPTInfo; + + maOutputRange.aStart.Set( static_cast< SCCOL >( maPTInfo.mnFirstCol ), static_cast< SCROW >( maPTInfo.mnFirstRow ), GetCurrScTab() ); + maOutputRange.aEnd.Set( static_cast< SCCOL >( maPTInfo.mnLastCol ), static_cast< SCROW >( maPTInfo.mnLastRow ), GetCurrScTab() ); + CheckCellRange( maOutputRange ); + + mpPCache = GetPivotTableManager().GetPivotCache( maPTInfo.mnCacheIdx ); + mpCurrField = 0; +} + +void XclImpPivotTable::ReadSxvd( XclImpStream& rStrm ) +{ + if( maFieldList.Count() < EXC_PT_MAXFIELDCOUNT ) + { + // cache index for the field is equal to the SXVD record index + sal_uInt16 nCacheIdx = static_cast< sal_uInt16 >( maFieldList.Count() ); + + mpCurrField = new XclImpPTField( *this, nCacheIdx ); + maFieldList.Append( mpCurrField ); + mpCurrField->ReadSxvd( rStrm ); + } + else + mpCurrField = 0; +} + +void XclImpPivotTable::ReadSxvi( XclImpStream& rStrm ) +{ + if( mpCurrField ) + mpCurrField->ReadSxvi( rStrm ); +} + +void XclImpPivotTable::ReadSxvdex( XclImpStream& rStrm ) +{ + if( mpCurrField ) + mpCurrField->ReadSxvdex( rStrm ); +} + +void XclImpPivotTable::ReadSxivd( XclImpStream& rStrm ) +{ + mpCurrField = 0; + + // find the index vector to fill (row SXIVD doesn't exist without row fields) + ScfUInt16Vec* pFieldVec = 0; + if( maRowFields.empty() && (maPTInfo.mnRowFields > 0) ) + pFieldVec = &maRowFields; + else if( maColFields.empty() && (maPTInfo.mnColFields > 0) ) + pFieldVec = &maColFields; + + // fill the vector from record data + if( pFieldVec ) + { + sal_uInt16 nSize = ::ulimit< sal_uInt16 >( rStrm.GetRecSize() / 2, EXC_PT_MAXROWCOLCOUNT ); + pFieldVec->reserve( nSize ); + for( sal_uInt16 nIdx = 0; nIdx < nSize; ++nIdx ) + { + sal_uInt16 nFieldIdx; + rStrm >> nFieldIdx; + pFieldVec->push_back( nFieldIdx ); + + // set orientation at special data orientation field + if( nFieldIdx == EXC_SXIVD_DATA ) + { + sal_uInt16 nAxis = (pFieldVec == &maRowFields) ? EXC_SXVD_AXIS_ROW : EXC_SXVD_AXIS_COL; + maDataOrientField.SetAxes( nAxis ); + } + } + } +} + +void XclImpPivotTable::ReadSxpi( XclImpStream& rStrm ) +{ + mpCurrField = 0; + + sal_uInt16 nSize = ::ulimit< sal_uInt16 >( rStrm.GetRecSize() / 6 ); + for( sal_uInt16 nEntry = 0; nEntry < nSize; ++nEntry ) + { + XclPTPageFieldInfo aPageInfo; + rStrm >> aPageInfo; + if( XclImpPTField* pField = GetFieldAcc( aPageInfo.mnField ) ) + { + maPageFields.push_back( aPageInfo.mnField ); + pField->SetPageFieldInfo( aPageInfo ); + } + GetObjectManager().SetSkipObj( GetCurrScTab(), aPageInfo.mnObjId ); + } +} + +void XclImpPivotTable::ReadSxdi( XclImpStream& rStrm ) +{ + mpCurrField = 0; + + XclPTDataFieldInfo aDataInfo; + rStrm >> aDataInfo; + if( XclImpPTField* pField = GetFieldAcc( aDataInfo.mnField ) ) + { + maOrigDataFields.push_back( aDataInfo.mnField ); + // DataPilot does not support double data fields -> add first appearence to index list only + if( !pField->HasDataFieldInfo() ) + maFiltDataFields.push_back( aDataInfo.mnField ); + pField->AddDataFieldInfo( aDataInfo ); + } +} + +// ---------------------------------------------------------------------------- + +void XclImpPivotTable::Apply() const +{ + if( !mpPCache || !mpPCache->IsSelfRef() || (mpPCache->GetSourceType() != EXC_SXVS_SHEET) ) + return; + + ScRange aSrcRange( mpPCache->GetSourceRange() ); + SCTAB nScTab = GetTabInfo().GetScTabFromXclName( mpPCache->GetTabName() ); + if( nScTab == SCNOTAB ) + return; + + ScDPSaveData aSaveData; + + // *** global settings *** + + aSaveData.SetRowGrand( ::get_flag( maPTInfo.mnFlags, EXC_SXVIEW_ROWGRAND ) ); + aSaveData.SetColumnGrand( ::get_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND ) ); + + // *** fields *** + + ScfUInt16Vec::const_iterator aIt, aEnd; + + // row fields + for( aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt ) + if( const XclImpPTField* pField = GetField( *aIt ) ) + pField->ApplyRowColField( aSaveData ); + + // column fields + for( aIt = maColFields.begin(), aEnd = maColFields.end(); aIt != aEnd; ++aIt ) + if( const XclImpPTField* pField = GetField( *aIt ) ) + pField->ApplyRowColField( aSaveData ); + + // page fields + for( aIt = maPageFields.begin(), aEnd = maPageFields.end(); aIt != aEnd; ++aIt ) + if( const XclImpPTField* pField = GetField( *aIt ) ) + pField->ApplyPageField( aSaveData ); + + // data fields + for( aIt = maFiltDataFields.begin(), aEnd = maFiltDataFields.end(); aIt != aEnd; ++aIt ) + if( const XclImpPTField* pField = GetField( *aIt ) ) + pField->ApplyDataField( aSaveData ); + + // *** insert into Calc document *** + + // create source descriptor + aSrcRange.aStart.SetTab( nScTab ); + aSrcRange.aEnd.SetTab( nScTab ); + ScSheetSourceDesc aDesc; + aDesc.aSourceRange = aSrcRange; + + // adjust output range to include the page fields + ScRange aOutRange( maOutputRange ); + SCsROW nDecRows = ::std::min< SCsROW >( maOutputRange.aStart.Row(), maPageFields.size() + 2 ); + aOutRange.aStart.IncRow( -nDecRows ); + + // create the DataPilot + ScDPObject* pDPObj = new ScDPObject( GetDocPtr() ); + pDPObj->SetName( maPTInfo.maTableName ); + pDPObj->SetSaveData( aSaveData ); + pDPObj->SetSheetDesc( aDesc ); + pDPObj->SetOutRange( aOutRange ); + pDPObj->SetAlive( TRUE ); + GetDoc().GetDPCollection()->Insert( pDPObj ); +} + +// ============================================================================ +// ============================================================================ + +XclImpPivotTableManager::XclImpPivotTableManager( const XclImpRoot& rRoot ) : + XclImpRoot( rRoot ) +{ +} + +XclImpPivotTableManager::~XclImpPivotTableManager() +{ +} + +// access functions ----------------------------------------------------------- + +const XclImpPivotCache* XclImpPivotTableManager::GetPivotCache( sal_uInt16 nCacheIdx ) const +{ + return maPCacheList.GetObject( nCacheIdx ); +} + +// pivot cache records -------------------------------------------------------- + +void XclImpPivotTableManager::ReadSxidstm( XclImpStream& rStrm ) +{ + sal_uInt16 nStrmId; + rStrm >> nStrmId; + maPCacheList.Append( new XclImpPivotCache( GetRoot(), nStrmId ) ); +} + +void XclImpPivotTableManager::ReadDconref( XclImpStream& rStrm ) +{ + if( !maPCacheList.Empty() ) + maPCacheList.Last()->ReadDconref( rStrm ); +} + +void XclImpPivotTableManager::ReadSxvs( XclImpStream& rStrm ) +{ + if( !maPCacheList.Empty() ) + maPCacheList.Last()->ReadSxvs( rStrm ); +} + +// pivot table records -------------------------------------------------------- + +void XclImpPivotTableManager::ReadSxview( XclImpStream& rStrm ) +{ + XclImpPivotTable* pPTable = new XclImpPivotTable( GetRoot() ); + maPTableList.Append( pPTable ); + pPTable->ReadSxview( rStrm ); +} + +void XclImpPivotTableManager::ReadSxvd( XclImpStream& rStrm ) +{ + if( !maPTableList.Empty() ) + maPTableList.Last()->ReadSxvd( rStrm ); +} + +void XclImpPivotTableManager::ReadSxvdex( XclImpStream& rStrm ) +{ + if( !maPTableList.Empty() ) + maPTableList.Last()->ReadSxvdex( rStrm ); +} + +void XclImpPivotTableManager::ReadSxivd( XclImpStream& rStrm ) +{ + if( !maPTableList.Empty() ) + maPTableList.Last()->ReadSxivd( rStrm ); +} + +void XclImpPivotTableManager::ReadSxpi( XclImpStream& rStrm ) +{ + if( !maPTableList.Empty() ) + maPTableList.Last()->ReadSxpi( rStrm ); +} + +void XclImpPivotTableManager::ReadSxdi( XclImpStream& rStrm ) +{ + if( !maPTableList.Empty() ) + maPTableList.Last()->ReadSxdi( rStrm ); +} + +void XclImpPivotTableManager::ReadSxvi( XclImpStream& rStrm ) +{ + if( !maPTableList.Empty() ) + maPTableList.Last()->ReadSxvi( rStrm ); +} + +// ---------------------------------------------------------------------------- + +void XclImpPivotTableManager::Apply() const +{ + for( const XclImpPivotTable* pPTable = maPTableList.First(); pPTable; pPTable = maPTableList.Next() ) + pPTable->Apply(); +} + +// ============================================================================ + |