| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| #include "dpgroup.hxx" |
| #include "dpsave.hxx" |
| #include "xestream.hxx" |
| #include "xistream.hxx" |
| #include "xestring.hxx" |
| #include "xlpivot.hxx" |
| #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> |
| |
| using ::com::sun::star::sheet::GeneralFunction; |
| using ::com::sun::star::sheet::DataPilotFieldOrientation; |
| |
| namespace ScDPSortMode = ::com::sun::star::sheet::DataPilotFieldSortMode; |
| namespace ScDPShowItemsMode = ::com::sun::star::sheet::DataPilotFieldShowItemsMode; |
| namespace ScDPLayoutMode = ::com::sun::star::sheet::DataPilotFieldLayoutMode; |
| namespace ScDPRefItemType = ::com::sun::star::sheet::DataPilotFieldReferenceItemType; |
| namespace ScDPGroupBy = ::com::sun::star::sheet::DataPilotFieldGroupBy; |
| |
| // ============================================================================ |
| // Pivot cache |
| // ============================================================================ |
| |
| XclPCItem::XclPCItem() : |
| meType( EXC_PCITEM_INVALID ) |
| { |
| } |
| |
| XclPCItem::~XclPCItem() |
| { |
| } |
| |
| void XclPCItem::SetEmpty() |
| { |
| meType = EXC_PCITEM_EMPTY; |
| maText.Erase(); |
| } |
| |
| void XclPCItem::SetText( const String& rText ) |
| { |
| meType = EXC_PCITEM_TEXT; |
| maText = rText; |
| } |
| |
| void XclPCItem::SetDouble( double fValue ) |
| { |
| meType = EXC_PCITEM_DOUBLE; |
| //! TODO convert double to string |
| maText.Erase(); |
| mfValue = fValue; |
| } |
| |
| void XclPCItem::SetDateTime( const DateTime& rDateTime ) |
| { |
| meType = EXC_PCITEM_DATETIME; |
| //! TODO convert date to string |
| maText.Erase(); |
| maDateTime = rDateTime; |
| } |
| |
| void XclPCItem::SetInteger( sal_Int16 nValue ) |
| { |
| meType = EXC_PCITEM_INTEGER; |
| maText = String::CreateFromInt32( nValue ); |
| mnValue = nValue; |
| } |
| |
| void XclPCItem::SetError( sal_uInt16 nError ) |
| { |
| meType = EXC_PCITEM_ERROR; |
| maText.Erase(); |
| mnError = nError; |
| switch( nError ) |
| { |
| case 0x00: maText = String::CreateFromAscii("#NULL!"); break; |
| case 0x07: maText = String::CreateFromAscii("#DIV/0!"); break; |
| case 0x0F: maText = String::CreateFromAscii("#VALUE!" ); break; |
| case 0x17: maText = String::CreateFromAscii("#REF!"); break; |
| case 0x1D: maText = String::CreateFromAscii("#NAME?"); break; |
| case 0x24: maText = String::CreateFromAscii("#NUM!" ); break; |
| case 0x2A: maText = String::CreateFromAscii("#N/A"); break; |
| default: break; |
| } |
| } |
| |
| void XclPCItem::SetBool( bool bValue ) |
| { |
| meType = EXC_PCITEM_BOOL; |
| //! TODO convert boolean to string |
| maText.Erase(); |
| mbValue = bValue; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| bool XclPCItem::IsEqual( const XclPCItem& rItem ) const |
| { |
| if( meType == rItem.meType ) switch( meType ) |
| { |
| case EXC_PCITEM_INVALID: return true; |
| case EXC_PCITEM_EMPTY: return true; |
| case EXC_PCITEM_TEXT: return maText == rItem.maText; |
| case EXC_PCITEM_DOUBLE: return mfValue == rItem.mfValue; |
| case EXC_PCITEM_DATETIME: return maDateTime == rItem.maDateTime; |
| case EXC_PCITEM_INTEGER: return mnValue == rItem.mnValue; |
| case EXC_PCITEM_BOOL: return mbValue == rItem.mbValue; |
| case EXC_PCITEM_ERROR: return mnError == rItem.mnError; |
| default: DBG_ERRORFILE( "XclPCItem::IsEqual - unknown pivot cache item type" ); |
| } |
| return false; |
| } |
| |
| bool XclPCItem::IsEmpty() const |
| { |
| return meType == EXC_PCITEM_EMPTY; |
| } |
| |
| const String* XclPCItem::GetText() const |
| { |
| return (meType == EXC_PCITEM_TEXT || meType == EXC_PCITEM_ERROR) ? &maText : NULL; |
| } |
| |
| const double* XclPCItem::GetDouble() const |
| { |
| return (meType == EXC_PCITEM_DOUBLE) ? &mfValue : 0; |
| } |
| |
| const DateTime* XclPCItem::GetDateTime() const |
| { |
| return (meType == EXC_PCITEM_DATETIME) ? &maDateTime : 0; |
| } |
| |
| const sal_Int16* XclPCItem::GetInteger() const |
| { |
| return (meType == EXC_PCITEM_INTEGER) ? &mnValue : 0; |
| } |
| |
| const sal_uInt16* XclPCItem::GetError() const |
| { |
| return (meType == EXC_PCITEM_ERROR) ? &mnError : 0; |
| } |
| |
| const bool* XclPCItem::GetBool() const |
| { |
| return (meType == EXC_PCITEM_BOOL) ? &mbValue : 0; |
| } |
| |
| const String* XclPCItem::GetItemName() const |
| { |
| //! TODO: use XclImpPCItem::ConvertToText(), if all conversions are available |
| if( EXC_PCITEM_BOOL == this->GetType() ) |
| { |
| static String szBool[] = { String::CreateFromAscii("FALSE"), String::CreateFromAscii("TRUE") }; |
| |
| if( const bool* pBool = this->GetBool() ) |
| { |
| return &(!!*pBool)[szBool]; |
| } |
| else |
| { |
| return &0[szBool]; |
| } |
| } |
| else |
| { |
| if( this->IsEmpty()) |
| { |
| static String aEmptyString( String::EmptyString() ); |
| return &aEmptyString; |
| } |
| else |
| return this->GetText(); |
| } |
| } |
| |
| |
| // Field settings ============================================================= |
| |
| XclPCFieldInfo::XclPCFieldInfo() : |
| mnFlags( 0 ), |
| mnGroupChild( 0 ), |
| mnGroupBase( 0 ), |
| mnVisItems( 0 ), |
| mnGroupItems( 0 ), |
| mnBaseItems( 0 ), |
| mnOrigItems( 0 ) |
| { |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPCFieldInfo& rInfo ) |
| { |
| rStrm >> rInfo.mnFlags |
| >> rInfo.mnGroupChild |
| >> rInfo.mnGroupBase |
| >> rInfo.mnVisItems |
| >> rInfo.mnGroupItems |
| >> rInfo.mnBaseItems |
| >> rInfo.mnOrigItems; |
| if( rStrm.GetRecLeft() >= 3 ) |
| rInfo.maName = rStrm.ReadUniString(); |
| else |
| rInfo.maName.Erase(); |
| return rStrm; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPCFieldInfo& rInfo ) |
| { |
| return rStrm |
| << rInfo.mnFlags |
| << rInfo.mnGroupChild |
| << rInfo.mnGroupBase |
| << rInfo.mnVisItems |
| << rInfo.mnGroupItems |
| << rInfo.mnBaseItems |
| << rInfo.mnOrigItems |
| << XclExpString( rInfo.maName ); |
| } |
| |
| // Numeric grouping field settings ============================================ |
| |
| XclPCNumGroupInfo::XclPCNumGroupInfo() : |
| mnFlags( EXC_SXNUMGROUP_AUTOMIN | EXC_SXNUMGROUP_AUTOMAX ) |
| { |
| SetNumType(); |
| } |
| |
| void XclPCNumGroupInfo::SetNumType() |
| { |
| SetXclDataType( EXC_SXNUMGROUP_TYPE_NUM ); |
| } |
| |
| sal_Int32 XclPCNumGroupInfo::GetScDateType() const |
| { |
| sal_Int32 nScType = 0; |
| switch( GetXclDataType() ) |
| { |
| case EXC_SXNUMGROUP_TYPE_SEC: nScType = ScDPGroupBy::SECONDS; break; |
| case EXC_SXNUMGROUP_TYPE_MIN: nScType = ScDPGroupBy::MINUTES; break; |
| case EXC_SXNUMGROUP_TYPE_HOUR: nScType = ScDPGroupBy::HOURS; break; |
| case EXC_SXNUMGROUP_TYPE_DAY: nScType = ScDPGroupBy::DAYS; break; |
| case EXC_SXNUMGROUP_TYPE_MONTH: nScType = ScDPGroupBy::MONTHS; break; |
| case EXC_SXNUMGROUP_TYPE_QUART: nScType = ScDPGroupBy::QUARTERS; break; |
| case EXC_SXNUMGROUP_TYPE_YEAR: nScType = ScDPGroupBy::YEARS; break; |
| default: DBG_ERROR1( "XclPCNumGroupInfo::GetScDateType - unexpected date type %d", GetXclDataType() ); |
| } |
| return nScType; |
| } |
| |
| void XclPCNumGroupInfo::SetScDateType( sal_Int32 nScType ) |
| { |
| sal_uInt16 nXclType = EXC_SXNUMGROUP_TYPE_NUM; |
| switch( nScType ) |
| { |
| case ScDPGroupBy::SECONDS: nXclType = EXC_SXNUMGROUP_TYPE_SEC; break; |
| case ScDPGroupBy::MINUTES: nXclType = EXC_SXNUMGROUP_TYPE_MIN; break; |
| case ScDPGroupBy::HOURS: nXclType = EXC_SXNUMGROUP_TYPE_HOUR; break; |
| case ScDPGroupBy::DAYS: nXclType = EXC_SXNUMGROUP_TYPE_DAY; break; |
| case ScDPGroupBy::MONTHS: nXclType = EXC_SXNUMGROUP_TYPE_MONTH; break; |
| case ScDPGroupBy::QUARTERS: nXclType = EXC_SXNUMGROUP_TYPE_QUART; break; |
| case ScDPGroupBy::YEARS: nXclType = EXC_SXNUMGROUP_TYPE_YEAR; break; |
| default: DBG_ERROR1( "XclPCNumGroupInfo::SetScDateType - unexpected date type %d", nScType ); |
| } |
| SetXclDataType( nXclType ); |
| } |
| |
| sal_uInt16 XclPCNumGroupInfo::GetXclDataType() const |
| { |
| return ::extract_value< sal_uInt16 >( mnFlags, 2, 4 ); |
| } |
| |
| void XclPCNumGroupInfo::SetXclDataType( sal_uInt16 nXclType ) |
| { |
| ::insert_value( mnFlags, nXclType, 2, 4 ); |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPCNumGroupInfo& rInfo ) |
| { |
| return rStrm >> rInfo.mnFlags; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPCNumGroupInfo& rInfo ) |
| { |
| return rStrm << rInfo.mnFlags; |
| } |
| |
| // Base class for pivot cache fields ========================================== |
| |
| XclPCField::XclPCField( XclPCFieldType eFieldType, sal_uInt16 nFieldIdx ) : |
| meFieldType( eFieldType ), |
| mnFieldIdx( nFieldIdx ) |
| { |
| } |
| |
| XclPCField::~XclPCField() |
| { |
| } |
| |
| bool XclPCField::IsSupportedField() const |
| { |
| return (meFieldType != EXC_PCFIELD_CALCED) && (meFieldType != EXC_PCFIELD_UNKNOWN); |
| } |
| |
| bool XclPCField::IsStandardField() const |
| { |
| return meFieldType == EXC_PCFIELD_STANDARD; |
| } |
| |
| //UNUSED2008-05 bool XclPCField::IsCalculatedField() const |
| //UNUSED2008-05 { |
| //UNUSED2008-05 return meFieldType == EXC_PCFIELD_CALCED; |
| //UNUSED2008-05 } |
| |
| bool XclPCField::IsStdGroupField() const |
| { |
| return meFieldType == EXC_PCFIELD_STDGROUP; |
| } |
| |
| bool XclPCField::IsNumGroupField() const |
| { |
| return meFieldType == EXC_PCFIELD_NUMGROUP; |
| } |
| |
| bool XclPCField::IsDateGroupField() const |
| { |
| return (meFieldType == EXC_PCFIELD_DATEGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD); |
| } |
| |
| bool XclPCField::IsGroupField() const |
| { |
| return IsStdGroupField() || IsNumGroupField() || IsDateGroupField(); |
| } |
| |
| bool XclPCField::IsGroupBaseField() const |
| { |
| return ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD ); |
| } |
| |
| bool XclPCField::IsGroupChildField() const |
| { |
| return (meFieldType == EXC_PCFIELD_STDGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD); |
| } |
| |
| sal_uInt16 XclPCField::GetBaseFieldIndex() const |
| { |
| return IsGroupChildField() ? maFieldInfo.mnGroupBase : mnFieldIdx; |
| } |
| |
| bool XclPCField::HasOrigItems() const |
| { |
| return IsSupportedField() && ((maFieldInfo.mnOrigItems > 0) || HasPostponedItems()); |
| } |
| |
| bool XclPCField::HasInlineItems() const |
| { |
| return (IsStandardField() || IsGroupField()) && ((maFieldInfo.mnGroupItems > 0) || (maFieldInfo.mnOrigItems > 0)); |
| } |
| |
| bool XclPCField::HasPostponedItems() const |
| { |
| return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_POSTPONE ); |
| } |
| |
| bool XclPCField::Has16BitIndexes() const |
| { |
| return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_16BIT ); |
| } |
| |
| // Pivot cache settings ======================================================= |
| |
| /** Contains data for a pivot cache (SXDB record). */ |
| XclPCInfo::XclPCInfo() : |
| mnSrcRecs( 0 ), |
| mnStrmId( 0xFFFF ), |
| mnFlags( EXC_SXDB_DEFAULTFLAGS ), |
| mnBlockRecs( EXC_SXDB_BLOCKRECS ), |
| mnStdFields( 0 ), |
| mnTotalFields( 0 ), |
| mnSrcType( EXC_SXDB_SRC_SHEET ) |
| { |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPCInfo& rInfo ) |
| { |
| rStrm >> rInfo.mnSrcRecs |
| >> rInfo.mnStrmId |
| >> rInfo.mnFlags |
| >> rInfo.mnBlockRecs |
| >> rInfo.mnStdFields |
| >> rInfo.mnTotalFields; |
| rStrm.Ignore( 2 ); |
| rStrm >> rInfo.mnSrcType; |
| rInfo.maUserName = rStrm.ReadUniString(); |
| return rStrm; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPCInfo& rInfo ) |
| { |
| return rStrm |
| << rInfo.mnSrcRecs |
| << rInfo.mnStrmId |
| << rInfo.mnFlags |
| << rInfo.mnBlockRecs |
| << rInfo.mnStdFields |
| << rInfo.mnTotalFields |
| << sal_uInt16( 0 ) |
| << rInfo.mnSrcType |
| << XclExpString( rInfo.maUserName ); |
| } |
| |
| // ============================================================================ |
| // Pivot table |
| // ============================================================================ |
| |
| // cached name ================================================================ |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPTCachedName& rCachedName ) |
| { |
| sal_uInt16 nStrLen; |
| rStrm >> nStrLen; |
| rCachedName.mbUseCache = nStrLen == EXC_PT_NOSTRING; |
| if( rCachedName.mbUseCache ) |
| rCachedName.maName.Erase(); |
| else |
| rCachedName.maName = rStrm.ReadUniString( nStrLen ); |
| return rStrm; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPTCachedName& rCachedName ) |
| { |
| if( rCachedName.mbUseCache ) |
| rStrm << EXC_PT_NOSTRING; |
| else |
| rStrm << XclExpString( rCachedName.maName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN ); |
| return rStrm; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| const String* XclPTVisNameInfo::GetVisName() const |
| { |
| return HasVisName() ? &maVisName.maName : 0; |
| } |
| |
| void XclPTVisNameInfo::SetVisName( const String& rName ) |
| { |
| maVisName.maName = rName; |
| maVisName.mbUseCache = rName.Len() == 0; |
| } |
| |
| // Field item settings ======================================================== |
| |
| XclPTItemInfo::XclPTItemInfo() : |
| mnType( EXC_SXVI_TYPE_DATA ), |
| mnFlags( EXC_SXVI_DEFAULTFLAGS ), |
| mnCacheIdx( EXC_SXVI_DEFAULT_CACHE ) |
| { |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPTItemInfo& rInfo ) |
| { |
| return rStrm |
| >> rInfo.mnType |
| >> rInfo.mnFlags |
| >> rInfo.mnCacheIdx |
| >> rInfo.maVisName; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPTItemInfo& rInfo ) |
| { |
| return rStrm |
| << rInfo.mnType |
| << rInfo.mnFlags |
| << rInfo.mnCacheIdx |
| << rInfo.maVisName; |
| } |
| |
| // General field settings ===================================================== |
| |
| XclPTFieldInfo::XclPTFieldInfo() : |
| mnAxes( EXC_SXVD_AXIS_NONE ), |
| mnSubtCount( 1 ), |
| mnSubtotals( EXC_SXVD_SUBT_DEFAULT ), |
| mnItemCount( 0 ), |
| mnCacheIdx( EXC_SXVD_DEFAULT_CACHE ) |
| { |
| } |
| |
| DataPilotFieldOrientation XclPTFieldInfo::GetApiOrient( sal_uInt16 nMask ) const |
| { |
| using namespace ::com::sun::star::sheet; |
| DataPilotFieldOrientation eOrient = DataPilotFieldOrientation_HIDDEN; |
| sal_uInt16 nUsedAxes = mnAxes & nMask; |
| if( nUsedAxes & EXC_SXVD_AXIS_ROW ) |
| eOrient = DataPilotFieldOrientation_ROW; |
| else if( nUsedAxes & EXC_SXVD_AXIS_COL ) |
| eOrient = DataPilotFieldOrientation_COLUMN; |
| else if( nUsedAxes & EXC_SXVD_AXIS_PAGE ) |
| eOrient = DataPilotFieldOrientation_PAGE; |
| else if( nUsedAxes & EXC_SXVD_AXIS_DATA ) |
| eOrient = DataPilotFieldOrientation_DATA; |
| return eOrient; |
| } |
| |
| void XclPTFieldInfo::AddApiOrient( DataPilotFieldOrientation eOrient ) |
| { |
| using namespace ::com::sun::star::sheet; |
| switch( eOrient ) |
| { |
| case DataPilotFieldOrientation_ROW: mnAxes |= EXC_SXVD_AXIS_ROW; break; |
| case DataPilotFieldOrientation_COLUMN: mnAxes |= EXC_SXVD_AXIS_COL; break; |
| case DataPilotFieldOrientation_PAGE: mnAxes |= EXC_SXVD_AXIS_PAGE; break; |
| case DataPilotFieldOrientation_DATA: mnAxes |= EXC_SXVD_AXIS_DATA; break; |
| default:; |
| } |
| } |
| |
| //! TODO: should be a Sequence<GeneralFunction> in ScDPSaveData |
| void XclPTFieldInfo::GetSubtotals( XclPTSubtotalVec& rSubtotals ) const |
| { |
| rSubtotals.clear(); |
| rSubtotals.reserve( 16 ); |
| |
| using namespace ::com::sun::star::sheet; |
| if( mnSubtotals & EXC_SXVD_SUBT_DEFAULT ) rSubtotals.push_back( GeneralFunction_AUTO ); |
| if( mnSubtotals & EXC_SXVD_SUBT_SUM ) rSubtotals.push_back( GeneralFunction_SUM ); |
| if( mnSubtotals & EXC_SXVD_SUBT_COUNT ) rSubtotals.push_back( GeneralFunction_COUNT ); |
| if( mnSubtotals & EXC_SXVD_SUBT_AVERAGE ) rSubtotals.push_back( GeneralFunction_AVERAGE ); |
| if( mnSubtotals & EXC_SXVD_SUBT_MAX ) rSubtotals.push_back( GeneralFunction_MAX ); |
| if( mnSubtotals & EXC_SXVD_SUBT_MIN ) rSubtotals.push_back( GeneralFunction_MIN ); |
| if( mnSubtotals & EXC_SXVD_SUBT_PROD ) rSubtotals.push_back( GeneralFunction_PRODUCT ); |
| if( mnSubtotals & EXC_SXVD_SUBT_COUNTNUM ) rSubtotals.push_back( GeneralFunction_COUNTNUMS ); |
| if( mnSubtotals & EXC_SXVD_SUBT_STDDEV ) rSubtotals.push_back( GeneralFunction_STDEV ); |
| if( mnSubtotals & EXC_SXVD_SUBT_STDDEVP ) rSubtotals.push_back( GeneralFunction_STDEVP ); |
| if( mnSubtotals & EXC_SXVD_SUBT_VAR ) rSubtotals.push_back( GeneralFunction_VAR ); |
| if( mnSubtotals & EXC_SXVD_SUBT_VARP ) rSubtotals.push_back( GeneralFunction_VARP ); |
| } |
| |
| void XclPTFieldInfo::SetSubtotals( const XclPTSubtotalVec& rSubtotals ) |
| { |
| mnSubtotals = EXC_SXVD_SUBT_NONE; |
| using namespace ::com::sun::star::sheet; |
| for( XclPTSubtotalVec::const_iterator aIt = rSubtotals.begin(), aEnd = rSubtotals.end(); aIt != aEnd; ++aIt ) |
| { |
| switch( *aIt ) |
| { |
| case GeneralFunction_AUTO: mnSubtotals |= EXC_SXVD_SUBT_DEFAULT; break; |
| case GeneralFunction_SUM: mnSubtotals |= EXC_SXVD_SUBT_SUM; break; |
| case GeneralFunction_COUNT: mnSubtotals |= EXC_SXVD_SUBT_COUNT; break; |
| case GeneralFunction_AVERAGE: mnSubtotals |= EXC_SXVD_SUBT_AVERAGE; break; |
| case GeneralFunction_MAX: mnSubtotals |= EXC_SXVD_SUBT_MAX; break; |
| case GeneralFunction_MIN: mnSubtotals |= EXC_SXVD_SUBT_MIN; break; |
| case GeneralFunction_PRODUCT: mnSubtotals |= EXC_SXVD_SUBT_PROD; break; |
| case GeneralFunction_COUNTNUMS: mnSubtotals |= EXC_SXVD_SUBT_COUNTNUM; break; |
| case GeneralFunction_STDEV: mnSubtotals |= EXC_SXVD_SUBT_STDDEV; break; |
| case GeneralFunction_STDEVP: mnSubtotals |= EXC_SXVD_SUBT_STDDEVP; break; |
| case GeneralFunction_VAR: mnSubtotals |= EXC_SXVD_SUBT_VAR; break; |
| case GeneralFunction_VARP: mnSubtotals |= EXC_SXVD_SUBT_VARP; break; |
| } |
| } |
| |
| mnSubtCount = 0; |
| for( sal_uInt16 nMask = 0x8000; nMask; nMask >>= 1 ) |
| if( mnSubtotals & nMask ) |
| ++mnSubtCount; |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldInfo& rInfo ) |
| { |
| // rInfo.mnCacheIdx is not part of the SXVD record |
| return rStrm |
| >> rInfo.mnAxes |
| >> rInfo.mnSubtCount |
| >> rInfo.mnSubtotals |
| >> rInfo.mnItemCount |
| >> rInfo.maVisName; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo ) |
| { |
| // rInfo.mnCacheIdx is not part of the SXVD record |
| return rStrm |
| << rInfo.mnAxes |
| << rInfo.mnSubtCount |
| << rInfo.mnSubtotals |
| << rInfo.mnItemCount |
| << rInfo.maVisName; |
| } |
| |
| // Extended field settings ==================================================== |
| |
| XclPTFieldExtInfo::XclPTFieldExtInfo() : |
| mnFlags( EXC_SXVDEX_DEFAULTFLAGS ), |
| mnSortField( EXC_SXVDEX_SORT_OWN ), |
| mnShowField( EXC_SXVDEX_SHOW_NONE ), |
| mnNumFmt(0), |
| mpFieldTotalName(NULL) |
| { |
| } |
| |
| sal_Int32 XclPTFieldExtInfo::GetApiSortMode() const |
| { |
| sal_Int32 nSortMode = ScDPSortMode::MANUAL; |
| if( ::get_flag( mnFlags, EXC_SXVDEX_SORT ) ) |
| nSortMode = (mnSortField == EXC_SXVDEX_SORT_OWN) ? ScDPSortMode::NAME : ScDPSortMode::DATA; |
| return nSortMode; |
| } |
| |
| void XclPTFieldExtInfo::SetApiSortMode( sal_Int32 nSortMode ) |
| { |
| bool bSort = (nSortMode == ScDPSortMode::NAME) || (nSortMode == ScDPSortMode::DATA); |
| ::set_flag( mnFlags, EXC_SXVDEX_SORT, bSort ); |
| if( nSortMode == ScDPSortMode::NAME ) |
| mnSortField = EXC_SXVDEX_SORT_OWN; // otherwise sort field has to be set by caller |
| } |
| |
| sal_Int32 XclPTFieldExtInfo::GetApiAutoShowMode() const |
| { |
| return ::get_flagvalue( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC, |
| ScDPShowItemsMode::FROM_TOP, ScDPShowItemsMode::FROM_BOTTOM ); |
| } |
| |
| void XclPTFieldExtInfo::SetApiAutoShowMode( sal_Int32 nShowMode ) |
| { |
| ::set_flag( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC, nShowMode == ScDPShowItemsMode::FROM_TOP ); |
| } |
| |
| sal_Int32 XclPTFieldExtInfo::GetApiAutoShowCount() const |
| { |
| return ::extract_value< sal_Int32 >( mnFlags, 24, 8 ); |
| } |
| |
| void XclPTFieldExtInfo::SetApiAutoShowCount( sal_Int32 nShowCount ) |
| { |
| ::insert_value( mnFlags, limit_cast< sal_uInt8 >( nShowCount ), 24, 8 ); |
| } |
| |
| sal_Int32 XclPTFieldExtInfo::GetApiLayoutMode() const |
| { |
| sal_Int32 nLayoutMode = ScDPLayoutMode::TABULAR_LAYOUT; |
| if( ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT ) ) |
| nLayoutMode = ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP ) ? |
| ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP : ScDPLayoutMode::OUTLINE_SUBTOTALS_BOTTOM; |
| return nLayoutMode; |
| } |
| |
| void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode ) |
| { |
| ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT, nLayoutMode != ScDPLayoutMode::TABULAR_LAYOUT ); |
| ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP, nLayoutMode == ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP ); |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo ) |
| { |
| sal_uInt8 nNameLen = 0; |
| rStrm >> rInfo.mnFlags |
| >> rInfo.mnSortField |
| >> rInfo.mnShowField |
| >> rInfo.mnNumFmt |
| >> nNameLen; |
| |
| rStrm.Ignore(10); |
| if (nNameLen != 0xFF) |
| // Custom field total name is used. Pick it up. |
| rInfo.mpFieldTotalName.reset(new rtl::OUString(rStrm.ReadUniString(nNameLen, 0))); |
| |
| return rStrm; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo ) |
| { |
| rStrm << rInfo.mnFlags |
| << rInfo.mnSortField |
| << rInfo.mnShowField |
| << EXC_SXVDEX_FORMAT_NONE; |
| |
| if (rInfo.mpFieldTotalName.get() && rInfo.mpFieldTotalName->getLength() > 0) |
| { |
| rtl::OUString aFinalName = *rInfo.mpFieldTotalName; |
| if (aFinalName.getLength() >= 254) |
| aFinalName = aFinalName.copy(0, 254); |
| sal_uInt8 nNameLen = static_cast<sal_uInt8>(aFinalName.getLength()); |
| rStrm << nNameLen; |
| rStrm.WriteZeroBytes(10); |
| rStrm << XclExpString(aFinalName, EXC_STR_NOHEADER); |
| } |
| else |
| { |
| rStrm << sal_uInt16(0xFFFF); |
| rStrm.WriteZeroBytes(8); |
| } |
| return rStrm; |
| } |
| |
| // Page field settings ======================================================== |
| |
| XclPTPageFieldInfo::XclPTPageFieldInfo() : |
| mnField( 0 ), |
| mnSelItem( EXC_SXPI_ALLITEMS ), |
| mnObjId( 0xFFFF ) |
| { |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPTPageFieldInfo& rInfo ) |
| { |
| return rStrm |
| >> rInfo.mnField |
| >> rInfo.mnSelItem |
| >> rInfo.mnObjId; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPTPageFieldInfo& rInfo ) |
| { |
| return rStrm |
| << rInfo.mnField |
| << rInfo.mnSelItem |
| << rInfo.mnObjId; |
| } |
| |
| // Data field settings ======================================================== |
| |
| XclPTDataFieldInfo::XclPTDataFieldInfo() : |
| mnField( 0 ), |
| mnAggFunc( EXC_SXDI_FUNC_SUM ), |
| mnRefType( EXC_SXDI_REF_NORMAL ), |
| mnRefField( 0 ), |
| mnRefItem( 0 ), |
| mnNumFmt( 0 ) |
| { |
| } |
| |
| GeneralFunction XclPTDataFieldInfo::GetApiAggFunc() const |
| { |
| using namespace ::com::sun::star::sheet; |
| GeneralFunction eAggFunc; |
| switch( mnAggFunc ) |
| { |
| case EXC_SXDI_FUNC_SUM: eAggFunc = GeneralFunction_SUM; break; |
| case EXC_SXDI_FUNC_COUNT: eAggFunc = GeneralFunction_COUNT; break; |
| case EXC_SXDI_FUNC_AVERAGE: eAggFunc = GeneralFunction_AVERAGE; break; |
| case EXC_SXDI_FUNC_MAX: eAggFunc = GeneralFunction_MAX; break; |
| case EXC_SXDI_FUNC_MIN: eAggFunc = GeneralFunction_MIN; break; |
| case EXC_SXDI_FUNC_PRODUCT: eAggFunc = GeneralFunction_PRODUCT; break; |
| case EXC_SXDI_FUNC_COUNTNUM: eAggFunc = GeneralFunction_COUNTNUMS; break; |
| case EXC_SXDI_FUNC_STDDEV: eAggFunc = GeneralFunction_STDEV; break; |
| case EXC_SXDI_FUNC_STDDEVP: eAggFunc = GeneralFunction_STDEVP; break; |
| case EXC_SXDI_FUNC_VAR: eAggFunc = GeneralFunction_VAR; break; |
| case EXC_SXDI_FUNC_VARP: eAggFunc = GeneralFunction_VARP; break; |
| default: eAggFunc = GeneralFunction_SUM; |
| } |
| return eAggFunc; |
| } |
| |
| void XclPTDataFieldInfo::SetApiAggFunc( GeneralFunction eAggFunc ) |
| { |
| using namespace ::com::sun::star::sheet; |
| switch( eAggFunc ) |
| { |
| case GeneralFunction_SUM: mnAggFunc = EXC_SXDI_FUNC_SUM; break; |
| case GeneralFunction_COUNT: mnAggFunc = EXC_SXDI_FUNC_COUNT; break; |
| case GeneralFunction_AVERAGE: mnAggFunc = EXC_SXDI_FUNC_AVERAGE; break; |
| case GeneralFunction_MAX: mnAggFunc = EXC_SXDI_FUNC_MAX; break; |
| case GeneralFunction_MIN: mnAggFunc = EXC_SXDI_FUNC_MIN; break; |
| case GeneralFunction_PRODUCT: mnAggFunc = EXC_SXDI_FUNC_PRODUCT; break; |
| case GeneralFunction_COUNTNUMS: mnAggFunc = EXC_SXDI_FUNC_COUNTNUM; break; |
| case GeneralFunction_STDEV: mnAggFunc = EXC_SXDI_FUNC_STDDEV; break; |
| case GeneralFunction_STDEVP: mnAggFunc = EXC_SXDI_FUNC_STDDEVP; break; |
| case GeneralFunction_VAR: mnAggFunc = EXC_SXDI_FUNC_VAR; break; |
| case GeneralFunction_VARP: mnAggFunc = EXC_SXDI_FUNC_VARP; break; |
| default: mnAggFunc = EXC_SXDI_FUNC_SUM; |
| } |
| } |
| |
| sal_Int32 XclPTDataFieldInfo::GetApiRefType() const |
| { |
| namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType; |
| sal_Int32 nRefType; |
| switch( mnRefType ) |
| { |
| case EXC_SXDI_REF_DIFF: nRefType = ScDPRefType::ITEM_DIFFERENCE; break; |
| case EXC_SXDI_REF_PERC: nRefType = ScDPRefType::ITEM_PERCENTAGE; break; |
| case EXC_SXDI_REF_PERC_DIFF: nRefType = ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE; break; |
| case EXC_SXDI_REF_RUN_TOTAL: nRefType = ScDPRefType::RUNNING_TOTAL; break; |
| case EXC_SXDI_REF_PERC_ROW: nRefType = ScDPRefType::ROW_PERCENTAGE; break; |
| case EXC_SXDI_REF_PERC_COL: nRefType = ScDPRefType::COLUMN_PERCENTAGE; break; |
| case EXC_SXDI_REF_PERC_TOTAL: nRefType = ScDPRefType::TOTAL_PERCENTAGE; break; |
| case EXC_SXDI_REF_INDEX: nRefType = ScDPRefType::INDEX; break; |
| default: nRefType = ScDPRefType::NONE; |
| } |
| return nRefType; |
| } |
| |
| void XclPTDataFieldInfo::SetApiRefType( sal_Int32 nRefType ) |
| { |
| namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType; |
| switch( nRefType ) |
| { |
| case ScDPRefType::ITEM_DIFFERENCE: mnRefType = EXC_SXDI_REF_DIFF; break; |
| case ScDPRefType::ITEM_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC; break; |
| case ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE: mnRefType = EXC_SXDI_REF_PERC_DIFF; break; |
| case ScDPRefType::RUNNING_TOTAL: mnRefType = EXC_SXDI_REF_RUN_TOTAL; break; |
| case ScDPRefType::ROW_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_ROW; break; |
| case ScDPRefType::COLUMN_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_COL; break; |
| case ScDPRefType::TOTAL_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_TOTAL;break; |
| case ScDPRefType::INDEX: mnRefType = EXC_SXDI_REF_INDEX; break; |
| default: mnRefType = EXC_SXDI_REF_NORMAL; |
| } |
| } |
| |
| sal_Int32 XclPTDataFieldInfo::GetApiRefItemType() const |
| { |
| sal_Int32 nRefItemType; |
| switch( mnRefItem ) |
| { |
| case EXC_SXDI_PREVITEM: nRefItemType = ScDPRefItemType::PREVIOUS; break; |
| case EXC_SXDI_NEXTITEM: nRefItemType = ScDPRefItemType::NEXT; break; |
| default: nRefItemType = ScDPRefItemType::NAMED; |
| } |
| return nRefItemType; |
| } |
| |
| void XclPTDataFieldInfo::SetApiRefItemType( sal_Int32 nRefItemType ) |
| { |
| switch( nRefItemType ) |
| { |
| case ScDPRefItemType::PREVIOUS: mnRefItem = EXC_SXDI_PREVITEM; break; |
| case ScDPRefItemType::NEXT: mnRefItem = EXC_SXDI_NEXTITEM; break; |
| // nothing for named item reference |
| } |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPTDataFieldInfo& rInfo ) |
| { |
| return rStrm |
| >> rInfo.mnField |
| >> rInfo.mnAggFunc |
| >> rInfo.mnRefType |
| >> rInfo.mnRefField |
| >> rInfo.mnRefItem |
| >> rInfo.mnNumFmt |
| >> rInfo.maVisName; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPTDataFieldInfo& rInfo ) |
| { |
| return rStrm |
| << rInfo.mnField |
| << rInfo.mnAggFunc |
| << rInfo.mnRefType |
| << rInfo.mnRefField |
| << rInfo.mnRefItem |
| << rInfo.mnNumFmt |
| << rInfo.maVisName; |
| } |
| |
| // Pivot table settings ======================================================= |
| |
| XclPTInfo::XclPTInfo() : |
| mnFirstHeadRow( 0 ), |
| mnCacheIdx( 0xFFFF ), |
| mnDataAxis( EXC_SXVD_AXIS_NONE ), |
| mnDataPos( EXC_SXVIEW_DATALAST ), |
| mnFields( 0 ), |
| mnRowFields( 0 ), |
| mnColFields( 0 ), |
| mnPageFields( 0 ), |
| mnDataFields( 0 ), |
| mnDataRows( 0 ), |
| mnDataCols( 0 ), |
| mnFlags( EXC_SXVIEW_DEFAULTFLAGS ), |
| mnAutoFmtIdx( EXC_SXVIEW_AUTOFMT ) |
| { |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPTInfo& rInfo ) |
| { |
| sal_uInt16 nTabLen, nDataLen; |
| |
| rStrm >> rInfo.maOutXclRange |
| >> rInfo.mnFirstHeadRow |
| >> rInfo.maDataXclPos |
| >> rInfo.mnCacheIdx; |
| rStrm.Ignore( 2 ); |
| rStrm >> rInfo.mnDataAxis >> rInfo.mnDataPos |
| >> rInfo.mnFields |
| >> rInfo.mnRowFields >> rInfo.mnColFields |
| >> rInfo.mnPageFields >> rInfo.mnDataFields |
| >> rInfo.mnDataRows >> rInfo.mnDataCols |
| >> rInfo.mnFlags |
| >> rInfo.mnAutoFmtIdx |
| >> nTabLen >> nDataLen; |
| rInfo.maTableName = rStrm.ReadUniString( nTabLen ); |
| rInfo.maDataName = rStrm.ReadUniString( nDataLen ); |
| return rStrm; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPTInfo& rInfo ) |
| { |
| XclExpString aXclTableName( rInfo.maTableName ); |
| XclExpString aXclDataName( rInfo.maDataName ); |
| |
| rStrm << rInfo.maOutXclRange |
| << rInfo.mnFirstHeadRow |
| << rInfo.maDataXclPos |
| << rInfo.mnCacheIdx |
| << sal_uInt16( 0 ) |
| << rInfo.mnDataAxis << rInfo.mnDataPos |
| << rInfo.mnFields |
| << rInfo.mnRowFields << rInfo.mnColFields |
| << rInfo.mnPageFields << rInfo.mnDataFields |
| << rInfo.mnDataRows << rInfo.mnDataCols |
| << rInfo.mnFlags |
| << rInfo.mnAutoFmtIdx |
| << aXclTableName.Len() << aXclDataName.Len(); |
| aXclTableName.WriteFlagField( rStrm ); |
| aXclTableName.WriteBuffer( rStrm ); |
| aXclDataName.WriteFlagField( rStrm ); |
| aXclDataName.WriteBuffer( rStrm ); |
| return rStrm; |
| } |
| |
| // Extended pivot table settings ============================================== |
| |
| XclPTExtInfo::XclPTExtInfo() : |
| mnSxformulaRecs( 0 ), |
| mnSxselectRecs( 0 ), |
| mnPagePerRow( 0 ), |
| mnPagePerCol( 0 ), |
| mnFlags( EXC_SXEX_DEFAULTFLAGS ) |
| { |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPTExtInfo& rInfo ) |
| { |
| rStrm >> rInfo.mnSxformulaRecs; |
| rStrm.Ignore( 6 ); |
| return rStrm |
| >> rInfo.mnSxselectRecs |
| >> rInfo.mnPagePerRow |
| >> rInfo.mnPagePerCol |
| >> rInfo.mnFlags; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo ) |
| { |
| return rStrm |
| << rInfo.mnSxformulaRecs |
| << EXC_PT_NOSTRING // length of alt. error text |
| << EXC_PT_NOSTRING // length of alt. empty text |
| << EXC_PT_NOSTRING // length of tag |
| << rInfo.mnSxselectRecs |
| << rInfo.mnPagePerRow |
| << rInfo.mnPagePerCol |
| << rInfo.mnFlags |
| << EXC_PT_NOSTRING // length of page field style name |
| << EXC_PT_NOSTRING // length of table style name |
| << EXC_PT_NOSTRING; // length of vacate style name |
| } |
| |
| // ============================================================================ |
| |
| // Pivot table autoformat settings ============================================ |
| |
| /** |
| classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00 |
| default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00 |
| report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00 |
| report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00 |
| report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00 |
| report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00 |
| report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00 |
| report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00 |
| report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00 |
| report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00 |
| report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00 |
| report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00 |
| table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00 |
| table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00 |
| table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00 |
| table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00 |
| table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00 |
| table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00 |
| table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00 |
| table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00 |
| table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00 |
| table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00 |
| none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00 |
| **/ |
| |
| XclPTViewEx9Info::XclPTViewEx9Info() : |
| mbReport( 0 ), |
| mnAutoFormat( 0 ), |
| mnGridLayout( 0x10 ) |
| { |
| } |
| |
| void XclPTViewEx9Info::Init( const ScDPObject& rDPObj ) |
| { |
| if( rDPObj.GetHeaderLayout() ) |
| { |
| mbReport = 0; |
| mnAutoFormat = 1; |
| mnGridLayout = 0; |
| } |
| else |
| { |
| // Report1 for now |
| // TODO : sync with autoformat indices |
| mbReport = 2; |
| mnAutoFormat = 1; |
| mnGridLayout = 0x10; |
| } |
| |
| const ScDPSaveData* pData = rDPObj.GetSaveData(); |
| if (pData) |
| { |
| const rtl::OUString* pGrandTotal = pData->GetGrandTotalName(); |
| if (pGrandTotal) |
| maGrandTotalName = *pGrandTotal; |
| } |
| } |
| |
| XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo ) |
| { |
| rStrm.Ignore( 2 ); |
| rStrm >> rInfo.mbReport; /// 2 for report* fmts ? |
| rStrm.Ignore( 6 ); |
| rStrm >> rInfo.mnAutoFormat >> rInfo.mnGridLayout; |
| rInfo.maGrandTotalName = rStrm.ReadUniString(); |
| return rStrm; |
| } |
| |
| XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo ) |
| { |
| return rStrm |
| << EXC_PT_AUTOFMT_HEADER |
| << rInfo.mbReport |
| << EXC_PT_AUTOFMT_ZERO |
| << EXC_PT_AUTOFMT_FLAGS |
| << rInfo.mnAutoFormat |
| << rInfo.mnGridLayout |
| << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN); |
| } |
| |