Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / source / filter / excel / xlpivot.cxx
blobaa7938762c780547a92ee4e5ca14519926a7f183
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <dpsave.hxx>
21 #include <xestream.hxx>
22 #include <xistream.hxx>
23 #include <xestring.hxx>
24 #include <xlpivot.hxx>
25 #include <generalfunction.hxx>
26 #include <osl/diagnose.h>
27 #include <sal/log.hxx>
28 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
29 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
30 #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
31 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
32 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
33 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
35 using ::com::sun::star::sheet::GeneralFunction;
36 using ::com::sun::star::sheet::DataPilotFieldOrientation;
38 namespace ScDPSortMode = ::com::sun::star::sheet::DataPilotFieldSortMode;
39 namespace ScDPShowItemsMode = ::com::sun::star::sheet::DataPilotFieldShowItemsMode;
40 namespace ScDPLayoutMode = ::com::sun::star::sheet::DataPilotFieldLayoutMode;
41 namespace ScDPRefItemType = ::com::sun::star::sheet::DataPilotFieldReferenceItemType;
42 namespace ScDPGroupBy = ::com::sun::star::sheet::DataPilotFieldGroupBy;
44 // Pivot cache
46 XclPCItem::XclPCItem() :
47 meType( EXC_PCITEM_INVALID ),
48 maDateTime( DateTime::EMPTY )
52 XclPCItem::~XclPCItem()
56 void XclPCItem::SetEmpty()
58 meType = EXC_PCITEM_EMPTY;
59 maText.clear();
62 void XclPCItem::SetText( const OUString& rText )
64 meType = EXC_PCITEM_TEXT;
65 maText = rText;
68 void XclPCItem::SetDouble( double fValue, const OUString& rText )
70 meType = EXC_PCITEM_DOUBLE;
71 maText = rText;
72 mfValue = fValue;
75 void XclPCItem::SetDateTime( const DateTime& rDateTime, const OUString& rText )
77 meType = EXC_PCITEM_DATETIME;
78 maText = rText;
79 maDateTime = rDateTime;
82 void XclPCItem::SetInteger( sal_Int16 nValue )
84 meType = EXC_PCITEM_INTEGER;
85 maText = OUString::number(nValue);
86 mnValue = nValue;
89 void XclPCItem::SetError( sal_uInt16 nError )
91 meType = EXC_PCITEM_ERROR;
92 maText.clear();
93 mnError = nError;
94 switch( nError )
96 case 0x00: maText = "#nullptr!"; break;
97 case 0x07: maText = "#DIV/0!"; break;
98 case 0x0F: maText = "#VALUE!"; break;
99 case 0x17: maText = "#REF!"; break;
100 case 0x1D: maText = "#NAME?"; break;
101 case 0x24: maText = "#NUM!"; break;
102 case 0x2A: maText = "#N/A"; break;
103 default: break;
107 void XclPCItem::SetBool( bool bValue, const OUString& rText )
109 meType = EXC_PCITEM_BOOL;
110 maText = rText;
111 mbValue = bValue;
114 bool XclPCItem::IsEqual( const XclPCItem& rItem ) const
116 if( meType == rItem.meType ) switch( meType )
118 case EXC_PCITEM_INVALID: return true;
119 case EXC_PCITEM_EMPTY: return true;
120 case EXC_PCITEM_TEXT: return maText == rItem.maText;
121 case EXC_PCITEM_DOUBLE: return mfValue == rItem.mfValue;
122 case EXC_PCITEM_DATETIME: return maDateTime == rItem.maDateTime;
123 case EXC_PCITEM_INTEGER: return mnValue == rItem.mnValue;
124 case EXC_PCITEM_BOOL: return mbValue == rItem.mbValue;
125 case EXC_PCITEM_ERROR: return mnError == rItem.mnError;
126 default: OSL_FAIL( "XclPCItem::IsEqual - unknown pivot cache item type" );
128 return false;
131 bool XclPCItem::IsEmpty() const
133 return meType == EXC_PCITEM_EMPTY;
136 const OUString* XclPCItem::GetText() const
138 return (meType == EXC_PCITEM_TEXT || meType == EXC_PCITEM_ERROR) ? &maText : nullptr;
141 const double* XclPCItem::GetDouble() const
143 return (meType == EXC_PCITEM_DOUBLE) ? &mfValue : nullptr;
146 const DateTime* XclPCItem::GetDateTime() const
148 return (meType == EXC_PCITEM_DATETIME) ? &maDateTime : nullptr;
151 const sal_Int16* XclPCItem::GetInteger() const
153 return (meType == EXC_PCITEM_INTEGER) ? &mnValue : nullptr;
156 const sal_uInt16* XclPCItem::GetError() const
158 return (meType == EXC_PCITEM_ERROR) ? &mnError : nullptr;
161 const bool* XclPCItem::GetBool() const
163 return (meType == EXC_PCITEM_BOOL) ? &mbValue : nullptr;
166 XclPCItemType XclPCItem::GetType() const
168 return meType;
171 // Field settings =============================================================
173 XclPCFieldInfo::XclPCFieldInfo() :
174 mnFlags( 0 ),
175 mnGroupChild( 0 ),
176 mnGroupBase( 0 ),
177 mnVisItems( 0 ),
178 mnGroupItems( 0 ),
179 mnBaseItems( 0 ),
180 mnOrigItems( 0 )
184 XclImpStream& operator>>( XclImpStream& rStrm, XclPCFieldInfo& rInfo )
186 rInfo.mnFlags = rStrm.ReaduInt16();
187 rInfo.mnGroupChild = rStrm.ReaduInt16();
188 rInfo.mnGroupBase = rStrm.ReaduInt16();
189 rInfo.mnVisItems = rStrm.ReaduInt16();
190 rInfo.mnGroupItems = rStrm.ReaduInt16();
191 rInfo.mnBaseItems = rStrm.ReaduInt16();
192 rInfo.mnOrigItems = rStrm.ReaduInt16();
193 if( rStrm.GetRecLeft() >= 3 )
194 rInfo.maName = rStrm.ReadUniString();
195 else
196 rInfo.maName.clear();
197 return rStrm;
200 XclExpStream& operator<<( XclExpStream& rStrm, const XclPCFieldInfo& rInfo )
202 return rStrm
203 << rInfo.mnFlags
204 << rInfo.mnGroupChild
205 << rInfo.mnGroupBase
206 << rInfo.mnVisItems
207 << rInfo.mnGroupItems
208 << rInfo.mnBaseItems
209 << rInfo.mnOrigItems
210 << XclExpString( rInfo.maName );
213 // Numeric grouping field settings ============================================
215 XclPCNumGroupInfo::XclPCNumGroupInfo() :
216 mnFlags( EXC_SXNUMGROUP_AUTOMIN | EXC_SXNUMGROUP_AUTOMAX )
218 SetNumType();
221 void XclPCNumGroupInfo::SetNumType()
223 SetXclDataType( EXC_SXNUMGROUP_TYPE_NUM );
226 sal_Int32 XclPCNumGroupInfo::GetScDateType() const
228 sal_Int32 nScType = 0;
229 switch( GetXclDataType() )
231 case EXC_SXNUMGROUP_TYPE_SEC: nScType = ScDPGroupBy::SECONDS; break;
232 case EXC_SXNUMGROUP_TYPE_MIN: nScType = ScDPGroupBy::MINUTES; break;
233 case EXC_SXNUMGROUP_TYPE_HOUR: nScType = ScDPGroupBy::HOURS; break;
234 case EXC_SXNUMGROUP_TYPE_DAY: nScType = ScDPGroupBy::DAYS; break;
235 case EXC_SXNUMGROUP_TYPE_MONTH: nScType = ScDPGroupBy::MONTHS; break;
236 case EXC_SXNUMGROUP_TYPE_QUART: nScType = ScDPGroupBy::QUARTERS; break;
237 case EXC_SXNUMGROUP_TYPE_YEAR: nScType = ScDPGroupBy::YEARS; break;
238 default: SAL_WARN("sc.filter", "XclPCNumGroupInfo::GetScDateType - unexpected date type " << GetXclDataType() );
240 return nScType;
243 void XclPCNumGroupInfo::SetScDateType( sal_Int32 nScType )
245 sal_uInt16 nXclType = EXC_SXNUMGROUP_TYPE_NUM;
246 switch( nScType )
248 case ScDPGroupBy::SECONDS: nXclType = EXC_SXNUMGROUP_TYPE_SEC; break;
249 case ScDPGroupBy::MINUTES: nXclType = EXC_SXNUMGROUP_TYPE_MIN; break;
250 case ScDPGroupBy::HOURS: nXclType = EXC_SXNUMGROUP_TYPE_HOUR; break;
251 case ScDPGroupBy::DAYS: nXclType = EXC_SXNUMGROUP_TYPE_DAY; break;
252 case ScDPGroupBy::MONTHS: nXclType = EXC_SXNUMGROUP_TYPE_MONTH; break;
253 case ScDPGroupBy::QUARTERS: nXclType = EXC_SXNUMGROUP_TYPE_QUART; break;
254 case ScDPGroupBy::YEARS: nXclType = EXC_SXNUMGROUP_TYPE_YEAR; break;
255 default:
256 SAL_INFO("sc.filter", "unexpected date type " << nScType);
258 SetXclDataType( nXclType );
261 sal_uInt16 XclPCNumGroupInfo::GetXclDataType() const
263 return ::extract_value< sal_uInt16 >( mnFlags, 2, 4 );
266 void XclPCNumGroupInfo::SetXclDataType( sal_uInt16 nXclType )
268 ::insert_value( mnFlags, nXclType, 2, 4 );
271 XclImpStream& operator>>( XclImpStream& rStrm, XclPCNumGroupInfo& rInfo )
273 rInfo.mnFlags = rStrm.ReaduInt16();
274 return rStrm;
277 XclExpStream& operator<<( XclExpStream& rStrm, const XclPCNumGroupInfo& rInfo )
279 return rStrm << rInfo.mnFlags;
282 // Base class for pivot cache fields ==========================================
284 XclPCField::XclPCField( XclPCFieldType eFieldType, sal_uInt16 nFieldIdx ) :
285 meFieldType( eFieldType ),
286 mnFieldIdx( nFieldIdx )
290 XclPCField::~XclPCField()
294 bool XclPCField::IsSupportedField() const
296 return (meFieldType != EXC_PCFIELD_CALCED) && (meFieldType != EXC_PCFIELD_UNKNOWN);
299 bool XclPCField::IsStandardField() const
301 return meFieldType == EXC_PCFIELD_STANDARD;
304 bool XclPCField::IsStdGroupField() const
306 return meFieldType == EXC_PCFIELD_STDGROUP;
309 bool XclPCField::IsNumGroupField() const
311 return meFieldType == EXC_PCFIELD_NUMGROUP;
314 bool XclPCField::IsDateGroupField() const
316 return (meFieldType == EXC_PCFIELD_DATEGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
319 bool XclPCField::IsGroupField() const
321 return IsStdGroupField() || IsNumGroupField() || IsDateGroupField();
324 bool XclPCField::IsGroupBaseField() const
326 return ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD );
329 bool XclPCField::IsGroupChildField() const
331 return (meFieldType == EXC_PCFIELD_STDGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
334 bool XclPCField::HasOrigItems() const
336 return IsSupportedField() && ((maFieldInfo.mnOrigItems > 0) || HasPostponedItems());
339 bool XclPCField::HasInlineItems() const
341 return (IsStandardField() || IsGroupField()) && ((maFieldInfo.mnGroupItems > 0) || (maFieldInfo.mnOrigItems > 0));
344 bool XclPCField::HasPostponedItems() const
346 return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_POSTPONE );
349 bool XclPCField::Has16BitIndexes() const
351 return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_16BIT );
354 // Pivot cache settings =======================================================
356 /** Contains data for a pivot cache (SXDB record). */
357 XclPCInfo::XclPCInfo() :
358 mnSrcRecs( 0 ),
359 mnStrmId( 0xFFFF ),
360 mnFlags( EXC_SXDB_DEFAULTFLAGS ),
361 mnBlockRecs( EXC_SXDB_BLOCKRECS ),
362 mnStdFields( 0 ),
363 mnTotalFields( 0 ),
364 mnSrcType( EXC_SXDB_SRC_SHEET )
368 XclImpStream& operator>>( XclImpStream& rStrm, XclPCInfo& rInfo )
370 rInfo.mnSrcRecs = rStrm.ReaduInt32();
371 rInfo.mnStrmId = rStrm.ReaduInt16();
372 rInfo.mnFlags = rStrm.ReaduInt16();
373 rInfo.mnBlockRecs = rStrm.ReaduInt16();
374 rInfo.mnStdFields = rStrm.ReaduInt16();
375 rInfo.mnTotalFields = rStrm.ReaduInt16();
376 rStrm.Ignore( 2 );
377 rInfo.mnSrcType = rStrm.ReaduInt16();
378 rInfo.maUserName = rStrm.ReadUniString();
379 return rStrm;
382 XclExpStream& operator<<( XclExpStream& rStrm, const XclPCInfo& rInfo )
384 return rStrm
385 << rInfo.mnSrcRecs
386 << rInfo.mnStrmId
387 << rInfo.mnFlags
388 << rInfo.mnBlockRecs
389 << rInfo.mnStdFields
390 << rInfo.mnTotalFields
391 << sal_uInt16( 0 )
392 << rInfo.mnSrcType
393 << XclExpString( rInfo.maUserName );
396 // Pivot table
398 // cached name ================================================================
400 XclImpStream& operator>>( XclImpStream& rStrm, XclPTCachedName& rCachedName )
402 sal_uInt16 nStrLen;
403 nStrLen = rStrm.ReaduInt16();
404 rCachedName.mbUseCache = nStrLen == EXC_PT_NOSTRING;
405 if( rCachedName.mbUseCache )
406 rCachedName.maName.clear();
407 else
408 rCachedName.maName = rStrm.ReadUniString( nStrLen );
409 return rStrm;
412 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTCachedName& rCachedName )
414 if( rCachedName.mbUseCache )
415 rStrm << EXC_PT_NOSTRING;
416 else
417 rStrm << XclExpString( rCachedName.maName, XclStrFlags::NONE, EXC_PT_MAXSTRLEN );
418 return rStrm;
421 const OUString* XclPTVisNameInfo::GetVisName() const
423 return HasVisName() ? &maVisName.maName : nullptr;
426 void XclPTVisNameInfo::SetVisName( const OUString& rName )
428 maVisName.maName = rName;
429 maVisName.mbUseCache = rName.isEmpty();
432 // Field item settings ========================================================
434 XclPTItemInfo::XclPTItemInfo() :
435 mnType( EXC_SXVI_TYPE_DATA ),
436 mnFlags( EXC_SXVI_DEFAULTFLAGS ),
437 mnCacheIdx( EXC_SXVI_DEFAULT_CACHE )
441 XclImpStream& operator>>( XclImpStream& rStrm, XclPTItemInfo& rInfo )
443 rInfo.mnType = rStrm.ReaduInt16();
444 rInfo.mnFlags = rStrm.ReaduInt16();
445 rInfo.mnCacheIdx = rStrm.ReaduInt16();
446 rStrm >> rInfo.maVisName;
447 return rStrm;
450 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTItemInfo& rInfo )
452 return rStrm
453 << rInfo.mnType
454 << rInfo.mnFlags
455 << rInfo.mnCacheIdx
456 << rInfo.maVisName;
459 // General field settings =====================================================
461 XclPTFieldInfo::XclPTFieldInfo() :
462 mnAxes( EXC_SXVD_AXIS_NONE ),
463 mnSubtCount( 1 ),
464 mnSubtotals( EXC_SXVD_SUBT_DEFAULT ),
465 mnItemCount( 0 ),
466 mnCacheIdx( EXC_SXVD_DEFAULT_CACHE )
470 DataPilotFieldOrientation XclPTFieldInfo::GetApiOrient( sal_uInt16 nMask ) const
472 using namespace ::com::sun::star::sheet;
473 DataPilotFieldOrientation eOrient = DataPilotFieldOrientation_HIDDEN;
474 sal_uInt16 nUsedAxes = mnAxes & nMask;
475 if( nUsedAxes & EXC_SXVD_AXIS_ROW )
476 eOrient = DataPilotFieldOrientation_ROW;
477 else if( nUsedAxes & EXC_SXVD_AXIS_COL )
478 eOrient = DataPilotFieldOrientation_COLUMN;
479 else if( nUsedAxes & EXC_SXVD_AXIS_PAGE )
480 eOrient = DataPilotFieldOrientation_PAGE;
481 else if( nUsedAxes & EXC_SXVD_AXIS_DATA )
482 eOrient = DataPilotFieldOrientation_DATA;
483 return eOrient;
486 void XclPTFieldInfo::AddApiOrient( DataPilotFieldOrientation eOrient )
488 using namespace ::com::sun::star::sheet;
489 switch( eOrient )
491 case DataPilotFieldOrientation_ROW: mnAxes |= EXC_SXVD_AXIS_ROW; break;
492 case DataPilotFieldOrientation_COLUMN: mnAxes |= EXC_SXVD_AXIS_COL; break;
493 case DataPilotFieldOrientation_PAGE: mnAxes |= EXC_SXVD_AXIS_PAGE; break;
494 case DataPilotFieldOrientation_DATA: mnAxes |= EXC_SXVD_AXIS_DATA; break;
495 default:;
499 //TODO: should be a Sequence<GeneralFunction> in ScDPSaveData
500 void XclPTFieldInfo::GetSubtotals( XclPTSubtotalVec& rSubtotals ) const
502 rSubtotals.clear();
503 rSubtotals.reserve( 16 );
505 if( mnSubtotals & EXC_SXVD_SUBT_DEFAULT ) rSubtotals.push_back( ScGeneralFunction::AUTO );
506 if( mnSubtotals & EXC_SXVD_SUBT_SUM ) rSubtotals.push_back( ScGeneralFunction::SUM );
507 if( mnSubtotals & EXC_SXVD_SUBT_COUNT ) rSubtotals.push_back( ScGeneralFunction::COUNT );
508 if( mnSubtotals & EXC_SXVD_SUBT_AVERAGE ) rSubtotals.push_back( ScGeneralFunction::AVERAGE );
509 if( mnSubtotals & EXC_SXVD_SUBT_MAX ) rSubtotals.push_back( ScGeneralFunction::MAX );
510 if( mnSubtotals & EXC_SXVD_SUBT_MIN ) rSubtotals.push_back( ScGeneralFunction::MIN );
511 if( mnSubtotals & EXC_SXVD_SUBT_PROD ) rSubtotals.push_back( ScGeneralFunction::PRODUCT );
512 if( mnSubtotals & EXC_SXVD_SUBT_COUNTNUM ) rSubtotals.push_back( ScGeneralFunction::COUNTNUMS );
513 if( mnSubtotals & EXC_SXVD_SUBT_STDDEV ) rSubtotals.push_back( ScGeneralFunction::STDEV );
514 if( mnSubtotals & EXC_SXVD_SUBT_STDDEVP ) rSubtotals.push_back( ScGeneralFunction::STDEVP );
515 if( mnSubtotals & EXC_SXVD_SUBT_VAR ) rSubtotals.push_back( ScGeneralFunction::VAR );
516 if( mnSubtotals & EXC_SXVD_SUBT_VARP ) rSubtotals.push_back( ScGeneralFunction::VARP );
519 void XclPTFieldInfo::SetSubtotals( const XclPTSubtotalVec& rSubtotals )
521 mnSubtotals = EXC_SXVD_SUBT_NONE;
522 for( const auto& rSubtotal : rSubtotals )
524 switch( rSubtotal )
526 case ScGeneralFunction::AUTO: mnSubtotals |= EXC_SXVD_SUBT_DEFAULT; break;
527 case ScGeneralFunction::SUM: mnSubtotals |= EXC_SXVD_SUBT_SUM; break;
528 case ScGeneralFunction::COUNT: mnSubtotals |= EXC_SXVD_SUBT_COUNT; break;
529 case ScGeneralFunction::AVERAGE: mnSubtotals |= EXC_SXVD_SUBT_AVERAGE; break;
530 case ScGeneralFunction::MAX: mnSubtotals |= EXC_SXVD_SUBT_MAX; break;
531 case ScGeneralFunction::MIN: mnSubtotals |= EXC_SXVD_SUBT_MIN; break;
532 case ScGeneralFunction::PRODUCT: mnSubtotals |= EXC_SXVD_SUBT_PROD; break;
533 case ScGeneralFunction::COUNTNUMS: mnSubtotals |= EXC_SXVD_SUBT_COUNTNUM; break;
534 case ScGeneralFunction::STDEV: mnSubtotals |= EXC_SXVD_SUBT_STDDEV; break;
535 case ScGeneralFunction::STDEVP: mnSubtotals |= EXC_SXVD_SUBT_STDDEVP; break;
536 case ScGeneralFunction::VAR: mnSubtotals |= EXC_SXVD_SUBT_VAR; break;
537 case ScGeneralFunction::VARP: mnSubtotals |= EXC_SXVD_SUBT_VARP; break;
538 default: break;
542 mnSubtCount = 0;
543 for( sal_uInt16 nMask = 0x8000; nMask; nMask >>= 1 )
544 if( mnSubtotals & nMask )
545 ++mnSubtCount;
548 XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldInfo& rInfo )
550 // rInfo.mnCacheIdx is not part of the SXVD record
551 rInfo.mnAxes = rStrm.ReaduInt16();
552 rInfo.mnSubtCount = rStrm.ReaduInt16();
553 rInfo.mnSubtotals = rStrm.ReaduInt16();
554 rInfo.mnItemCount = rStrm.ReaduInt16();
555 rStrm >> rInfo.maVisName;
556 return rStrm;
559 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo )
561 // rInfo.mnCacheIdx is not part of the SXVD record
562 return rStrm
563 << rInfo.mnAxes
564 << rInfo.mnSubtCount
565 << rInfo.mnSubtotals
566 << rInfo.mnItemCount
567 << rInfo.maVisName;
570 // Extended field settings ====================================================
572 XclPTFieldExtInfo::XclPTFieldExtInfo() :
573 mnFlags( EXC_SXVDEX_DEFAULTFLAGS ),
574 mnSortField( EXC_SXVDEX_SORT_OWN ),
575 mnShowField( EXC_SXVDEX_SHOW_NONE ),
576 mnNumFmt(0)
580 sal_Int32 XclPTFieldExtInfo::GetApiSortMode() const
582 sal_Int32 nSortMode = ScDPSortMode::MANUAL;
583 if( ::get_flag( mnFlags, EXC_SXVDEX_SORT ) )
584 nSortMode = (mnSortField == EXC_SXVDEX_SORT_OWN) ? ScDPSortMode::NAME : ScDPSortMode::DATA;
585 return nSortMode;
588 void XclPTFieldExtInfo::SetApiSortMode( sal_Int32 nSortMode )
590 bool bSort = (nSortMode == ScDPSortMode::NAME) || (nSortMode == ScDPSortMode::DATA);
591 ::set_flag( mnFlags, EXC_SXVDEX_SORT, bSort );
592 if( nSortMode == ScDPSortMode::NAME )
593 mnSortField = EXC_SXVDEX_SORT_OWN; // otherwise sort field has to be set by caller
596 sal_Int32 XclPTFieldExtInfo::GetApiAutoShowMode() const
598 return ::get_flagvalue( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC,
599 ScDPShowItemsMode::FROM_TOP, ScDPShowItemsMode::FROM_BOTTOM );
602 void XclPTFieldExtInfo::SetApiAutoShowMode( sal_Int32 nShowMode )
604 ::set_flag( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC, nShowMode == ScDPShowItemsMode::FROM_TOP );
607 sal_Int32 XclPTFieldExtInfo::GetApiAutoShowCount() const
609 return ::extract_value< sal_Int32 >( mnFlags, 24, 8 );
612 void XclPTFieldExtInfo::SetApiAutoShowCount( sal_Int32 nShowCount )
614 ::insert_value( mnFlags, limit_cast< sal_uInt8 >( nShowCount ), 24, 8 );
617 sal_Int32 XclPTFieldExtInfo::GetApiLayoutMode() const
619 sal_Int32 nLayoutMode = ScDPLayoutMode::TABULAR_LAYOUT;
620 if( ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT ) )
621 nLayoutMode = ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP ) ?
622 ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP : ScDPLayoutMode::OUTLINE_SUBTOTALS_BOTTOM;
623 return nLayoutMode;
626 void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode )
628 ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT, nLayoutMode != ScDPLayoutMode::TABULAR_LAYOUT );
629 ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP, nLayoutMode == ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP );
632 XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo )
634 sal_uInt8 nNameLen = 0;
635 rInfo.mnFlags = rStrm.ReaduInt32();
636 rInfo.mnSortField = rStrm.ReaduInt16();
637 rInfo.mnShowField = rStrm.ReaduInt16();
638 rInfo.mnNumFmt = rStrm.ReaduInt16();
639 nNameLen = rStrm.ReaduInt8();
641 rStrm.Ignore(10);
642 if (nNameLen != 0xFF)
643 // Custom field total name is used. Pick it up.
644 rInfo.mpFieldTotalName = rStrm.ReadUniString(nNameLen, 0);
646 return rStrm;
649 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
651 rStrm << rInfo.mnFlags
652 << rInfo.mnSortField
653 << rInfo.mnShowField
654 << EXC_SXVDEX_FORMAT_NONE;
656 if (rInfo.mpFieldTotalName && !rInfo.mpFieldTotalName->isEmpty())
658 OUString aFinalName = *rInfo.mpFieldTotalName;
659 if (aFinalName.getLength() >= 254)
660 aFinalName = aFinalName.copy(0, 254);
661 sal_uInt8 nNameLen = static_cast<sal_uInt8>(aFinalName.getLength());
662 rStrm << nNameLen;
663 rStrm.WriteZeroBytes(10);
664 rStrm << XclExpString(aFinalName, XclStrFlags::NoHeader);
666 else
668 rStrm << sal_uInt16(0xFFFF);
669 rStrm.WriteZeroBytes(8);
671 return rStrm;
674 // Page field settings ========================================================
676 XclPTPageFieldInfo::XclPTPageFieldInfo() :
677 mnField( 0 ),
678 mnSelItem( EXC_SXPI_ALLITEMS ),
679 mnObjId( 0xFFFF )
683 XclImpStream& operator>>( XclImpStream& rStrm, XclPTPageFieldInfo& rInfo )
685 rInfo.mnField = rStrm.ReaduInt16();
686 rInfo.mnSelItem = rStrm.ReaduInt16();
687 rInfo.mnObjId = rStrm.ReaduInt16();
688 return rStrm;
691 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTPageFieldInfo& rInfo )
693 return rStrm
694 << rInfo.mnField
695 << rInfo.mnSelItem
696 << rInfo.mnObjId;
699 // Data field settings ========================================================
701 XclPTDataFieldInfo::XclPTDataFieldInfo() :
702 mnField( 0 ),
703 mnAggFunc( EXC_SXDI_FUNC_SUM ),
704 mnRefType( EXC_SXDI_REF_NORMAL ),
705 mnRefField( 0 ),
706 mnRefItem( 0 ),
707 mnNumFmt( 0 )
711 ScGeneralFunction XclPTDataFieldInfo::GetApiAggFunc() const
713 ScGeneralFunction eAggFunc;
714 switch( mnAggFunc )
716 case EXC_SXDI_FUNC_SUM: eAggFunc = ScGeneralFunction::SUM; break;
717 case EXC_SXDI_FUNC_COUNT: eAggFunc = ScGeneralFunction::COUNT; break;
718 case EXC_SXDI_FUNC_AVERAGE: eAggFunc = ScGeneralFunction::AVERAGE; break;
719 case EXC_SXDI_FUNC_MAX: eAggFunc = ScGeneralFunction::MAX; break;
720 case EXC_SXDI_FUNC_MIN: eAggFunc = ScGeneralFunction::MIN; break;
721 case EXC_SXDI_FUNC_PRODUCT: eAggFunc = ScGeneralFunction::PRODUCT; break;
722 case EXC_SXDI_FUNC_COUNTNUM: eAggFunc = ScGeneralFunction::COUNTNUMS; break;
723 case EXC_SXDI_FUNC_STDDEV: eAggFunc = ScGeneralFunction::STDEV; break;
724 case EXC_SXDI_FUNC_STDDEVP: eAggFunc = ScGeneralFunction::STDEVP; break;
725 case EXC_SXDI_FUNC_VAR: eAggFunc = ScGeneralFunction::VAR; break;
726 case EXC_SXDI_FUNC_VARP: eAggFunc = ScGeneralFunction::VARP; break;
727 default: eAggFunc = ScGeneralFunction::SUM;
729 return eAggFunc;
732 void XclPTDataFieldInfo::SetApiAggFunc( ScGeneralFunction eAggFunc )
734 switch( eAggFunc )
736 case ScGeneralFunction::SUM: mnAggFunc = EXC_SXDI_FUNC_SUM; break;
737 case ScGeneralFunction::COUNT: mnAggFunc = EXC_SXDI_FUNC_COUNT; break;
738 case ScGeneralFunction::AVERAGE: mnAggFunc = EXC_SXDI_FUNC_AVERAGE; break;
739 case ScGeneralFunction::MAX: mnAggFunc = EXC_SXDI_FUNC_MAX; break;
740 case ScGeneralFunction::MIN: mnAggFunc = EXC_SXDI_FUNC_MIN; break;
741 case ScGeneralFunction::PRODUCT: mnAggFunc = EXC_SXDI_FUNC_PRODUCT; break;
742 case ScGeneralFunction::COUNTNUMS: mnAggFunc = EXC_SXDI_FUNC_COUNTNUM; break;
743 case ScGeneralFunction::STDEV: mnAggFunc = EXC_SXDI_FUNC_STDDEV; break;
744 case ScGeneralFunction::STDEVP: mnAggFunc = EXC_SXDI_FUNC_STDDEVP; break;
745 case ScGeneralFunction::VAR: mnAggFunc = EXC_SXDI_FUNC_VAR; break;
746 case ScGeneralFunction::VARP: mnAggFunc = EXC_SXDI_FUNC_VARP; break;
747 default: mnAggFunc = EXC_SXDI_FUNC_SUM;
751 sal_Int32 XclPTDataFieldInfo::GetApiRefType() const
753 namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
754 sal_Int32 nRefType;
755 switch( mnRefType )
757 case EXC_SXDI_REF_DIFF: nRefType = ScDPRefType::ITEM_DIFFERENCE; break;
758 case EXC_SXDI_REF_PERC: nRefType = ScDPRefType::ITEM_PERCENTAGE; break;
759 case EXC_SXDI_REF_PERC_DIFF: nRefType = ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE; break;
760 case EXC_SXDI_REF_RUN_TOTAL: nRefType = ScDPRefType::RUNNING_TOTAL; break;
761 case EXC_SXDI_REF_PERC_ROW: nRefType = ScDPRefType::ROW_PERCENTAGE; break;
762 case EXC_SXDI_REF_PERC_COL: nRefType = ScDPRefType::COLUMN_PERCENTAGE; break;
763 case EXC_SXDI_REF_PERC_TOTAL: nRefType = ScDPRefType::TOTAL_PERCENTAGE; break;
764 case EXC_SXDI_REF_INDEX: nRefType = ScDPRefType::INDEX; break;
765 default: nRefType = ScDPRefType::NONE;
767 return nRefType;
770 void XclPTDataFieldInfo::SetApiRefType( sal_Int32 nRefType )
772 namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
773 switch( nRefType )
775 case ScDPRefType::ITEM_DIFFERENCE: mnRefType = EXC_SXDI_REF_DIFF; break;
776 case ScDPRefType::ITEM_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC; break;
777 case ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE: mnRefType = EXC_SXDI_REF_PERC_DIFF; break;
778 case ScDPRefType::RUNNING_TOTAL: mnRefType = EXC_SXDI_REF_RUN_TOTAL; break;
779 case ScDPRefType::ROW_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_ROW; break;
780 case ScDPRefType::COLUMN_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_COL; break;
781 case ScDPRefType::TOTAL_PERCENTAGE: mnRefType = EXC_SXDI_REF_PERC_TOTAL;break;
782 case ScDPRefType::INDEX: mnRefType = EXC_SXDI_REF_INDEX; break;
783 default: mnRefType = EXC_SXDI_REF_NORMAL;
787 sal_Int32 XclPTDataFieldInfo::GetApiRefItemType() const
789 sal_Int32 nRefItemType;
790 switch( mnRefItem )
792 case EXC_SXDI_PREVITEM: nRefItemType = ScDPRefItemType::PREVIOUS; break;
793 case EXC_SXDI_NEXTITEM: nRefItemType = ScDPRefItemType::NEXT; break;
794 default: nRefItemType = ScDPRefItemType::NAMED;
796 return nRefItemType;
799 void XclPTDataFieldInfo::SetApiRefItemType( sal_Int32 nRefItemType )
801 switch( nRefItemType )
803 case ScDPRefItemType::PREVIOUS: mnRefItem = EXC_SXDI_PREVITEM; break;
804 case ScDPRefItemType::NEXT: mnRefItem = EXC_SXDI_NEXTITEM; break;
805 // nothing for named item reference
809 XclImpStream& operator>>( XclImpStream& rStrm, XclPTDataFieldInfo& rInfo )
811 rInfo.mnField = rStrm.ReaduInt16();
812 rInfo.mnAggFunc = rStrm.ReaduInt16();
813 rInfo.mnRefType = rStrm.ReaduInt16();
814 rInfo.mnRefField = rStrm.ReaduInt16();
815 rInfo.mnRefItem = rStrm.ReaduInt16();
816 rInfo.mnNumFmt = rStrm.ReaduInt16();
817 rStrm >> rInfo.maVisName;
818 return rStrm;
821 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTDataFieldInfo& rInfo )
823 return rStrm
824 << rInfo.mnField
825 << rInfo.mnAggFunc
826 << rInfo.mnRefType
827 << rInfo.mnRefField
828 << rInfo.mnRefItem
829 << rInfo.mnNumFmt
830 << rInfo.maVisName;
833 // Pivot table settings =======================================================
835 XclPTInfo::XclPTInfo() :
836 mnFirstHeadRow( 0 ),
837 mnCacheIdx( 0xFFFF ),
838 mnDataAxis( EXC_SXVD_AXIS_NONE ),
839 mnDataPos( EXC_SXVIEW_DATALAST ),
840 mnFields( 0 ),
841 mnRowFields( 0 ),
842 mnColFields( 0 ),
843 mnPageFields( 0 ),
844 mnDataFields( 0 ),
845 mnDataRows( 0 ),
846 mnDataCols( 0 ),
847 mnFlags( EXC_SXVIEW_DEFAULTFLAGS ),
848 mnAutoFmtIdx( EXC_SXVIEW_AUTOFMT )
852 XclImpStream& operator>>( XclImpStream& rStrm, XclPTInfo& rInfo )
854 sal_uInt16 nTabLen, nDataLen;
856 rStrm >> rInfo.maOutXclRange;
857 rInfo.mnFirstHeadRow = rStrm.ReaduInt16();
858 rStrm >> rInfo.maDataXclPos;
859 rInfo.mnCacheIdx = rStrm.ReaduInt16();
860 rStrm.Ignore( 2 );
861 rInfo.mnDataAxis = rStrm.ReaduInt16();
862 rInfo.mnDataPos = rStrm.ReaduInt16();
863 rInfo.mnFields = rStrm.ReaduInt16();
864 rInfo.mnRowFields = rStrm.ReaduInt16();
865 rInfo.mnColFields = rStrm.ReaduInt16();
866 rInfo.mnPageFields = rStrm.ReaduInt16();
867 rInfo.mnDataFields = rStrm.ReaduInt16();
868 rInfo.mnDataRows = rStrm.ReaduInt16();
869 rInfo.mnDataCols = rStrm.ReaduInt16();
870 rInfo.mnFlags = rStrm.ReaduInt16();
871 rInfo.mnAutoFmtIdx = rStrm.ReaduInt16();
872 nTabLen = rStrm.ReaduInt16();
873 nDataLen = rStrm.ReaduInt16();
874 rInfo.maTableName = rStrm.ReadUniString( nTabLen );
875 rInfo.maDataName = rStrm.ReadUniString( nDataLen );
876 return rStrm;
879 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTInfo& rInfo )
881 XclExpString aXclTableName( rInfo.maTableName );
882 XclExpString aXclDataName( rInfo.maDataName );
884 rStrm << rInfo.maOutXclRange
885 << rInfo.mnFirstHeadRow
886 << rInfo.maDataXclPos
887 << rInfo.mnCacheIdx
888 << sal_uInt16( 0 )
889 << rInfo.mnDataAxis << rInfo.mnDataPos
890 << rInfo.mnFields
891 << rInfo.mnRowFields << rInfo.mnColFields
892 << rInfo.mnPageFields << rInfo.mnDataFields
893 << rInfo.mnDataRows << rInfo.mnDataCols
894 << rInfo.mnFlags
895 << rInfo.mnAutoFmtIdx
896 << aXclTableName.Len() << aXclDataName.Len();
897 aXclTableName.WriteFlagField( rStrm );
898 aXclTableName.WriteBuffer( rStrm );
899 aXclDataName.WriteFlagField( rStrm );
900 aXclDataName.WriteBuffer( rStrm );
901 return rStrm;
904 // Extended pivot table settings ==============================================
906 XclPTExtInfo::XclPTExtInfo() :
907 mnSxformulaRecs( 0 ),
908 mnSxselectRecs( 0 ),
909 mnPagePerRow( 0 ),
910 mnPagePerCol( 0 ),
911 mnFlags( EXC_SXEX_DEFAULTFLAGS )
915 XclImpStream& operator>>( XclImpStream& rStrm, XclPTExtInfo& rInfo )
917 rInfo.mnSxformulaRecs = rStrm.ReaduInt16();
918 rStrm.Ignore( 6 );
919 rInfo.mnSxselectRecs = rStrm.ReaduInt16();
920 rInfo.mnPagePerRow = rStrm.ReaduInt16();
921 rInfo.mnPagePerCol = rStrm.ReaduInt16();
922 rInfo.mnFlags = rStrm.ReaduInt32();
923 return rStrm;
926 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo )
928 return rStrm
929 << rInfo.mnSxformulaRecs
930 << EXC_PT_NOSTRING // length of alt. error text
931 << EXC_PT_NOSTRING // length of alt. empty text
932 << EXC_PT_NOSTRING // length of tag
933 << rInfo.mnSxselectRecs
934 << rInfo.mnPagePerRow
935 << rInfo.mnPagePerCol
936 << rInfo.mnFlags
937 << EXC_PT_NOSTRING // length of page field style name
938 << EXC_PT_NOSTRING // length of table style name
939 << EXC_PT_NOSTRING; // length of vacate style name
942 // Pivot table autoformat settings ============================================
945 classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
946 default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
947 report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00
948 report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00
949 report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00
950 report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00
951 report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00
952 report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00
953 report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00
954 report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00
955 report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00
956 report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00
957 table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00
958 table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00
959 table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00
960 table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00
961 table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00
962 table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00
963 table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00
964 table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00
965 table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00
966 table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00
967 none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00
970 XclPTViewEx9Info::XclPTViewEx9Info() :
971 mbReport( 0 ),
972 mnAutoFormat( 0 ),
973 mnGridLayout( 0x10 )
977 void XclPTViewEx9Info::Init( const ScDPObject& rDPObj )
979 if( rDPObj.GetHeaderLayout() )
981 mbReport = 0;
982 mnAutoFormat = 1;
983 mnGridLayout = 0;
985 else
987 // Report1 for now
988 // TODO : sync with autoformat indices
989 mbReport = 2;
990 mnAutoFormat = 1;
991 mnGridLayout = 0x10;
994 const ScDPSaveData* pData = rDPObj.GetSaveData();
995 if (pData)
997 const boost::optional<OUString> & pGrandTotal = pData->GetGrandTotalName();
998 if (pGrandTotal)
999 maGrandTotalName = *pGrandTotal;
1003 XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo )
1005 rStrm.Ignore( 2 );
1006 rInfo.mbReport = rStrm.ReaduInt32(); /// 2 for report* fmts ?
1007 rStrm.Ignore( 6 );
1008 rInfo.mnAutoFormat = rStrm.ReaduInt8();
1009 rInfo.mnGridLayout = rStrm.ReaduInt8();
1010 rInfo.maGrandTotalName = rStrm.ReadUniString();
1011 return rStrm;
1014 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo )
1016 return rStrm
1017 << EXC_PT_AUTOFMT_HEADER
1018 << rInfo.mbReport
1019 << EXC_PT_AUTOFMT_ZERO
1020 << EXC_PT_AUTOFMT_FLAGS
1021 << rInfo.mnAutoFormat
1022 << rInfo.mnGridLayout
1023 << XclExpString(rInfo.maGrandTotalName, XclStrFlags::NONE, EXC_PT_MAXSTRLEN);
1026 XclPTAddl::XclPTAddl() :
1027 mbCompactMode(false)
1031 XclImpStream& operator>>(XclImpStream& rStrm, XclPTAddl& rInfo)
1033 rStrm.Ignore(4);
1034 sal_uInt8 sxc = rStrm.ReaduInt8();
1035 sal_uInt8 sxd = rStrm.ReaduInt8();
1036 if(sxc == 0x00 && sxd == 0x19) // SxcView / sxdVer12Info
1038 sal_uInt32 nFlags = rStrm.ReaduInt32();
1039 rInfo.mbCompactMode = ((nFlags & 0x00000008) != 0);
1041 return rStrm;
1044 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */