diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sc/source/filter/excel/xlpivot.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/source/filter/excel/xlpivot.cxx')
-rw-r--r-- | sc/source/filter/excel/xlpivot.cxx | 1043 |
1 files changed, 1043 insertions, 0 deletions
diff --git a/sc/source/filter/excel/xlpivot.cxx b/sc/source/filter/excel/xlpivot.cxx new file mode 100644 index 000000000..d18ab7416 --- /dev/null +++ b/sc/source/filter/excel/xlpivot.cxx @@ -0,0 +1,1043 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <dpsave.hxx> +#include <xestream.hxx> +#include <xistream.hxx> +#include <xestring.hxx> +#include <xlpivot.hxx> +#include <generalfunction.hxx> +#include <osl/diagnose.h> +#include <sal/log.hxx> +#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> +#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp> +#include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp> +#include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp> +#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp> +#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp> + +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 ), + maDateTime( DateTime::EMPTY ) +{ +} + +XclPCItem::~XclPCItem() +{ +} + +void XclPCItem::SetEmpty() +{ + meType = EXC_PCITEM_EMPTY; + maText.clear(); +} + +void XclPCItem::SetText( const OUString& rText ) +{ + meType = EXC_PCITEM_TEXT; + maText = rText; +} + +void XclPCItem::SetDouble( double fValue, const OUString& rText ) +{ + meType = EXC_PCITEM_DOUBLE; + maText = rText; + mfValue = fValue; +} + +void XclPCItem::SetDateTime( const DateTime& rDateTime, const OUString& rText ) +{ + meType = EXC_PCITEM_DATETIME; + maText = rText; + maDateTime = rDateTime; +} + +void XclPCItem::SetInteger( sal_Int16 nValue ) +{ + meType = EXC_PCITEM_INTEGER; + maText = OUString::number(nValue); + mnValue = nValue; +} + +void XclPCItem::SetError( sal_uInt16 nError ) +{ + meType = EXC_PCITEM_ERROR; + maText.clear(); + mnError = nError; + switch( nError ) + { + case 0x00: maText = "#nullptr!"; break; + case 0x07: maText = "#DIV/0!"; break; + case 0x0F: maText = "#VALUE!"; break; + case 0x17: maText = "#REF!"; break; + case 0x1D: maText = "#NAME?"; break; + case 0x24: maText = "#NUM!"; break; + case 0x2A: maText = "#N/A"; break; + default: break; + } +} + +void XclPCItem::SetBool( bool bValue, const OUString& rText ) +{ + meType = EXC_PCITEM_BOOL; + maText = rText; + 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: OSL_FAIL( "XclPCItem::IsEqual - unknown pivot cache item type" ); + } + return false; +} + +bool XclPCItem::IsEmpty() const +{ + return meType == EXC_PCITEM_EMPTY; +} + +const OUString* XclPCItem::GetText() const +{ + return (meType == EXC_PCITEM_TEXT || meType == EXC_PCITEM_ERROR) ? &maText : nullptr; +} + +const double* XclPCItem::GetDouble() const +{ + return (meType == EXC_PCITEM_DOUBLE) ? &mfValue : nullptr; +} + +const DateTime* XclPCItem::GetDateTime() const +{ + return (meType == EXC_PCITEM_DATETIME) ? &maDateTime : nullptr; +} + +const sal_Int16* XclPCItem::GetInteger() const +{ + return (meType == EXC_PCITEM_INTEGER) ? &mnValue : nullptr; +} + +const sal_uInt16* XclPCItem::GetError() const +{ + return (meType == EXC_PCITEM_ERROR) ? &mnError : nullptr; +} + +const bool* XclPCItem::GetBool() const +{ + return (meType == EXC_PCITEM_BOOL) ? &mbValue : nullptr; +} + +XclPCItemType XclPCItem::GetType() const +{ + return meType; +} + +// Field settings ============================================================= + +XclPCFieldInfo::XclPCFieldInfo() : + mnFlags( 0 ), + mnGroupChild( 0 ), + mnGroupBase( 0 ), + mnVisItems( 0 ), + mnGroupItems( 0 ), + mnBaseItems( 0 ), + mnOrigItems( 0 ) +{ +} + +XclImpStream& operator>>( XclImpStream& rStrm, XclPCFieldInfo& rInfo ) +{ + rInfo.mnFlags = rStrm.ReaduInt16(); + rInfo.mnGroupChild = rStrm.ReaduInt16(); + rInfo.mnGroupBase = rStrm.ReaduInt16(); + rInfo.mnVisItems = rStrm.ReaduInt16(); + rInfo.mnGroupItems = rStrm.ReaduInt16(); + rInfo.mnBaseItems = rStrm.ReaduInt16(); + rInfo.mnOrigItems = rStrm.ReaduInt16(); + if( rStrm.GetRecLeft() >= 3 ) + rInfo.maName = rStrm.ReadUniString(); + else + rInfo.maName.clear(); + 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: SAL_WARN("sc.filter", "XclPCNumGroupInfo::GetScDateType - unexpected date type " << 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: + SAL_INFO("sc.filter", "unexpected date type " << 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 ) +{ + rInfo.mnFlags = rStrm.ReaduInt16(); + return rStrm; +} + +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; +} + +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); +} + +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 ) +{ + rInfo.mnSrcRecs = rStrm.ReaduInt32(); + rInfo.mnStrmId = rStrm.ReaduInt16(); + rInfo.mnFlags = rStrm.ReaduInt16(); + rInfo.mnBlockRecs = rStrm.ReaduInt16(); + rInfo.mnStdFields = rStrm.ReaduInt16(); + rInfo.mnTotalFields = rStrm.ReaduInt16(); + rStrm.Ignore( 2 ); + rInfo.mnSrcType = rStrm.ReaduInt16(); + 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; + nStrLen = rStrm.ReaduInt16(); + rCachedName.mbUseCache = nStrLen == EXC_PT_NOSTRING; + if( rCachedName.mbUseCache ) + rCachedName.maName.clear(); + 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, XclStrFlags::NONE, EXC_PT_MAXSTRLEN ); + return rStrm; +} + +const OUString* XclPTVisNameInfo::GetVisName() const +{ + return HasVisName() ? &maVisName.maName : nullptr; +} + +void XclPTVisNameInfo::SetVisName( const OUString& rName ) +{ + maVisName.maName = rName; + maVisName.mbUseCache = rName.isEmpty(); +} + +// 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 ) +{ + rInfo.mnType = rStrm.ReaduInt16(); + rInfo.mnFlags = rStrm.ReaduInt16(); + rInfo.mnCacheIdx = rStrm.ReaduInt16(); + rStrm >> rInfo.maVisName; + return rStrm; +} + +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 ); + + if( mnSubtotals & EXC_SXVD_SUBT_DEFAULT ) rSubtotals.push_back( ScGeneralFunction::AUTO ); + if( mnSubtotals & EXC_SXVD_SUBT_SUM ) rSubtotals.push_back( ScGeneralFunction::SUM ); + if( mnSubtotals & EXC_SXVD_SUBT_COUNT ) rSubtotals.push_back( ScGeneralFunction::COUNT ); + if( mnSubtotals & EXC_SXVD_SUBT_AVERAGE ) rSubtotals.push_back( ScGeneralFunction::AVERAGE ); + if( mnSubtotals & EXC_SXVD_SUBT_MAX ) rSubtotals.push_back( ScGeneralFunction::MAX ); + if( mnSubtotals & EXC_SXVD_SUBT_MIN ) rSubtotals.push_back( ScGeneralFunction::MIN ); + if( mnSubtotals & EXC_SXVD_SUBT_PROD ) rSubtotals.push_back( ScGeneralFunction::PRODUCT ); + if( mnSubtotals & EXC_SXVD_SUBT_COUNTNUM ) rSubtotals.push_back( ScGeneralFunction::COUNTNUMS ); + if( mnSubtotals & EXC_SXVD_SUBT_STDDEV ) rSubtotals.push_back( ScGeneralFunction::STDEV ); + if( mnSubtotals & EXC_SXVD_SUBT_STDDEVP ) rSubtotals.push_back( ScGeneralFunction::STDEVP ); + if( mnSubtotals & EXC_SXVD_SUBT_VAR ) rSubtotals.push_back( ScGeneralFunction::VAR ); + if( mnSubtotals & EXC_SXVD_SUBT_VARP ) rSubtotals.push_back( ScGeneralFunction::VARP ); +} + +void XclPTFieldInfo::SetSubtotals( const XclPTSubtotalVec& rSubtotals ) +{ + mnSubtotals = EXC_SXVD_SUBT_NONE; + for( const auto& rSubtotal : rSubtotals ) + { + switch( rSubtotal ) + { + case ScGeneralFunction::AUTO: mnSubtotals |= EXC_SXVD_SUBT_DEFAULT; break; + case ScGeneralFunction::SUM: mnSubtotals |= EXC_SXVD_SUBT_SUM; break; + case ScGeneralFunction::COUNT: mnSubtotals |= EXC_SXVD_SUBT_COUNT; break; + case ScGeneralFunction::AVERAGE: mnSubtotals |= EXC_SXVD_SUBT_AVERAGE; break; + case ScGeneralFunction::MAX: mnSubtotals |= EXC_SXVD_SUBT_MAX; break; + case ScGeneralFunction::MIN: mnSubtotals |= EXC_SXVD_SUBT_MIN; break; + case ScGeneralFunction::PRODUCT: mnSubtotals |= EXC_SXVD_SUBT_PROD; break; + case ScGeneralFunction::COUNTNUMS: mnSubtotals |= EXC_SXVD_SUBT_COUNTNUM; break; + case ScGeneralFunction::STDEV: mnSubtotals |= EXC_SXVD_SUBT_STDDEV; break; + case ScGeneralFunction::STDEVP: mnSubtotals |= EXC_SXVD_SUBT_STDDEVP; break; + case ScGeneralFunction::VAR: mnSubtotals |= EXC_SXVD_SUBT_VAR; break; + case ScGeneralFunction::VARP: mnSubtotals |= EXC_SXVD_SUBT_VARP; break; + default: 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 + rInfo.mnAxes = rStrm.ReaduInt16(); + rInfo.mnSubtCount = rStrm.ReaduInt16(); + rInfo.mnSubtotals = rStrm.ReaduInt16(); + rInfo.mnItemCount = rStrm.ReaduInt16(); + rStrm >> rInfo.maVisName; + return rStrm; +} + +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) +{ +} + +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; + rInfo.mnFlags = rStrm.ReaduInt32(); + rInfo.mnSortField = rStrm.ReaduInt16(); + rInfo.mnShowField = rStrm.ReaduInt16(); + rInfo.mnNumFmt = rStrm.ReaduInt16(); + nNameLen = rStrm.ReaduInt8(); + + rStrm.Ignore(10); + if (nNameLen != 0xFF) + // Custom field total name is used. Pick it up. + rInfo.mpFieldTotalName = 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 && !rInfo.mpFieldTotalName->isEmpty()) + { + 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, XclStrFlags::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 ) +{ + rInfo.mnField = rStrm.ReaduInt16(); + rInfo.mnSelItem = rStrm.ReaduInt16(); + rInfo.mnObjId = rStrm.ReaduInt16(); + return rStrm; +} + +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 ) +{ +} + +ScGeneralFunction XclPTDataFieldInfo::GetApiAggFunc() const +{ + ScGeneralFunction eAggFunc; + switch( mnAggFunc ) + { + case EXC_SXDI_FUNC_SUM: eAggFunc = ScGeneralFunction::SUM; break; + case EXC_SXDI_FUNC_COUNT: eAggFunc = ScGeneralFunction::COUNT; break; + case EXC_SXDI_FUNC_AVERAGE: eAggFunc = ScGeneralFunction::AVERAGE; break; + case EXC_SXDI_FUNC_MAX: eAggFunc = ScGeneralFunction::MAX; break; + case EXC_SXDI_FUNC_MIN: eAggFunc = ScGeneralFunction::MIN; break; + case EXC_SXDI_FUNC_PRODUCT: eAggFunc = ScGeneralFunction::PRODUCT; break; + case EXC_SXDI_FUNC_COUNTNUM: eAggFunc = ScGeneralFunction::COUNTNUMS; break; + case EXC_SXDI_FUNC_STDDEV: eAggFunc = ScGeneralFunction::STDEV; break; + case EXC_SXDI_FUNC_STDDEVP: eAggFunc = ScGeneralFunction::STDEVP; break; + case EXC_SXDI_FUNC_VAR: eAggFunc = ScGeneralFunction::VAR; break; + case EXC_SXDI_FUNC_VARP: eAggFunc = ScGeneralFunction::VARP; break; + default: eAggFunc = ScGeneralFunction::SUM; + } + return eAggFunc; +} + +void XclPTDataFieldInfo::SetApiAggFunc( ScGeneralFunction eAggFunc ) +{ + switch( eAggFunc ) + { + case ScGeneralFunction::SUM: mnAggFunc = EXC_SXDI_FUNC_SUM; break; + case ScGeneralFunction::COUNT: mnAggFunc = EXC_SXDI_FUNC_COUNT; break; + case ScGeneralFunction::AVERAGE: mnAggFunc = EXC_SXDI_FUNC_AVERAGE; break; + case ScGeneralFunction::MAX: mnAggFunc = EXC_SXDI_FUNC_MAX; break; + case ScGeneralFunction::MIN: mnAggFunc = EXC_SXDI_FUNC_MIN; break; + case ScGeneralFunction::PRODUCT: mnAggFunc = EXC_SXDI_FUNC_PRODUCT; break; + case ScGeneralFunction::COUNTNUMS: mnAggFunc = EXC_SXDI_FUNC_COUNTNUM; break; + case ScGeneralFunction::STDEV: mnAggFunc = EXC_SXDI_FUNC_STDDEV; break; + case ScGeneralFunction::STDEVP: mnAggFunc = EXC_SXDI_FUNC_STDDEVP; break; + case ScGeneralFunction::VAR: mnAggFunc = EXC_SXDI_FUNC_VAR; break; + case ScGeneralFunction::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 ) +{ + rInfo.mnField = rStrm.ReaduInt16(); + rInfo.mnAggFunc = rStrm.ReaduInt16(); + rInfo.mnRefType = rStrm.ReaduInt16(); + rInfo.mnRefField = rStrm.ReaduInt16(); + rInfo.mnRefItem = rStrm.ReaduInt16(); + rInfo.mnNumFmt = rStrm.ReaduInt16(); + rStrm >> rInfo.maVisName; + return rStrm; +} + +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 = rStrm.ReaduInt16(); + rStrm >> rInfo.maDataXclPos; + rInfo.mnCacheIdx = rStrm.ReaduInt16(); + rStrm.Ignore( 2 ); + rInfo.mnDataAxis = rStrm.ReaduInt16(); + rInfo.mnDataPos = rStrm.ReaduInt16(); + rInfo.mnFields = rStrm.ReaduInt16(); + rInfo.mnRowFields = rStrm.ReaduInt16(); + rInfo.mnColFields = rStrm.ReaduInt16(); + rInfo.mnPageFields = rStrm.ReaduInt16(); + rInfo.mnDataFields = rStrm.ReaduInt16(); + rInfo.mnDataRows = rStrm.ReaduInt16(); + rInfo.mnDataCols = rStrm.ReaduInt16(); + rInfo.mnFlags = rStrm.ReaduInt16(); + rInfo.mnAutoFmtIdx = rStrm.ReaduInt16(); + nTabLen = rStrm.ReaduInt16(); + nDataLen = rStrm.ReaduInt16(); + 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 ) +{ + rInfo.mnSxformulaRecs = rStrm.ReaduInt16(); + rStrm.Ignore( 6 ); + rInfo.mnSxselectRecs = rStrm.ReaduInt16(); + rInfo.mnPagePerRow = rStrm.ReaduInt16(); + rInfo.mnPagePerCol = rStrm.ReaduInt16(); + rInfo.mnFlags = rStrm.ReaduInt32(); + return rStrm; +} + +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 std::optional<OUString> & pGrandTotal = pData->GetGrandTotalName(); + if (pGrandTotal) + maGrandTotalName = *pGrandTotal; + } +} + +XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo ) +{ + rStrm.Ignore( 2 ); + rInfo.mbReport = rStrm.ReaduInt32(); /// 2 for report* fmts ? + rStrm.Ignore( 6 ); + rInfo.mnAutoFormat = rStrm.ReaduInt8(); + rInfo.mnGridLayout = rStrm.ReaduInt8(); + 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, XclStrFlags::NONE, EXC_PT_MAXSTRLEN); +} + +XclPTAddl::XclPTAddl() : + mbCompactMode(false) +{ +} + +XclImpStream& operator>>(XclImpStream& rStrm, XclPTAddl& rInfo) +{ + rStrm.Ignore(4); + sal_uInt8 sxc = rStrm.ReaduInt8(); + sal_uInt8 sxd = rStrm.ReaduInt8(); + if(sxc == 0x00 && sxd == 0x19) // SxcView / sxdVer12Info + { + sal_uInt32 nFlags = rStrm.ReaduInt32(); + rInfo.mbCompactMode = ((nFlags & 0x00000008) != 0); + } + return rStrm; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |