xref: /trunk/main/sc/source/filter/excel/xlpivot.cxx (revision b77af630)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scfilt.hxx"
26 #include "dpgroup.hxx"
27 #include "dpsave.hxx"
28 #include "xestream.hxx"
29 #include "xistream.hxx"
30 #include "xestring.hxx"
31 #include "xlpivot.hxx"
32 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
33 
34 using ::com::sun::star::sheet::GeneralFunction;
35 using ::com::sun::star::sheet::DataPilotFieldOrientation;
36 
37 namespace ScDPSortMode = ::com::sun::star::sheet::DataPilotFieldSortMode;
38 namespace ScDPShowItemsMode = ::com::sun::star::sheet::DataPilotFieldShowItemsMode;
39 namespace ScDPLayoutMode = ::com::sun::star::sheet::DataPilotFieldLayoutMode;
40 namespace ScDPRefItemType = ::com::sun::star::sheet::DataPilotFieldReferenceItemType;
41 namespace ScDPGroupBy = ::com::sun::star::sheet::DataPilotFieldGroupBy;
42 
43 // ============================================================================
44 // Pivot cache
45 // ============================================================================
46 
XclPCItem()47 XclPCItem::XclPCItem() :
48     meType( EXC_PCITEM_INVALID )
49 {
50 }
51 
~XclPCItem()52 XclPCItem::~XclPCItem()
53 {
54 }
55 
SetEmpty()56 void XclPCItem::SetEmpty()
57 {
58     meType = EXC_PCITEM_EMPTY;
59     maText.Erase();
60 }
61 
SetText(const String & rText)62 void XclPCItem::SetText( const String& rText )
63 {
64     meType = EXC_PCITEM_TEXT;
65     maText = rText;
66 }
67 
SetDouble(double fValue)68 void XclPCItem::SetDouble( double fValue )
69 {
70     meType = EXC_PCITEM_DOUBLE;
71     //! TODO convert double to string
72     maText.Erase();
73     mfValue = fValue;
74 }
75 
SetDateTime(const DateTime & rDateTime)76 void XclPCItem::SetDateTime( const DateTime& rDateTime )
77 {
78     meType = EXC_PCITEM_DATETIME;
79     //! TODO convert date to string
80     maText.Erase();
81     maDateTime = rDateTime;
82 }
83 
SetInteger(sal_Int16 nValue)84 void XclPCItem::SetInteger( sal_Int16 nValue )
85 {
86     meType = EXC_PCITEM_INTEGER;
87     maText = String::CreateFromInt32( nValue );
88     mnValue = nValue;
89 }
90 
SetError(sal_uInt16 nError)91 void XclPCItem::SetError( sal_uInt16 nError )
92 {
93     meType = EXC_PCITEM_ERROR;
94     maText.Erase();
95     mnError = nError;
96     switch( nError )
97     {
98     case 0x00: maText = String::CreateFromAscii("#NULL!"); break;
99     case 0x07: maText = String::CreateFromAscii("#DIV/0!"); break;
100     case 0x0F: maText = String::CreateFromAscii("#VALUE!" ); break;
101     case 0x17: maText = String::CreateFromAscii("#REF!"); break;
102     case 0x1D: maText = String::CreateFromAscii("#NAME?"); break;
103     case 0x24: maText = String::CreateFromAscii("#NUM!" ); break;
104     case 0x2A: maText = String::CreateFromAscii("#N/A"); break;
105     default: break;
106     }
107 }
108 
SetBool(bool bValue)109 void XclPCItem::SetBool( bool bValue )
110 {
111     meType = EXC_PCITEM_BOOL;
112     //! TODO convert boolean to string
113     maText.Erase();
114     mbValue = bValue;
115 }
116 
117 // ----------------------------------------------------------------------------
118 
IsEqual(const XclPCItem & rItem) const119 bool XclPCItem::IsEqual( const XclPCItem& rItem ) const
120 {
121     if( meType == rItem.meType ) switch( meType )
122     {
123         case EXC_PCITEM_INVALID:    return true;
124         case EXC_PCITEM_EMPTY:      return true;
125         case EXC_PCITEM_TEXT:       return maText     == rItem.maText;
126         case EXC_PCITEM_DOUBLE:     return mfValue    == rItem.mfValue;
127         case EXC_PCITEM_DATETIME:   return maDateTime == rItem.maDateTime;
128         case EXC_PCITEM_INTEGER:    return mnValue    == rItem.mnValue;
129         case EXC_PCITEM_BOOL:       return mbValue    == rItem.mbValue;
130         case EXC_PCITEM_ERROR:      return mnError    == rItem.mnError;
131         default:    DBG_ERRORFILE( "XclPCItem::IsEqual - unknown pivot cache item type" );
132     }
133     return false;
134 }
135 
IsEmpty() const136 bool XclPCItem::IsEmpty() const
137 {
138     return meType == EXC_PCITEM_EMPTY;
139 }
140 
GetText() const141 const String* XclPCItem::GetText() const
142 {
143     return (meType == EXC_PCITEM_TEXT || meType == EXC_PCITEM_ERROR) ? &maText : NULL;
144 }
145 
GetDouble() const146 const double* XclPCItem::GetDouble() const
147 {
148     return (meType == EXC_PCITEM_DOUBLE) ? &mfValue : 0;
149 }
150 
GetDateTime() const151 const DateTime* XclPCItem::GetDateTime() const
152 {
153     return (meType == EXC_PCITEM_DATETIME) ? &maDateTime : 0;
154 }
155 
GetInteger() const156 const sal_Int16* XclPCItem::GetInteger() const
157 {
158     return (meType == EXC_PCITEM_INTEGER) ? &mnValue : 0;
159 }
160 
GetError() const161 const sal_uInt16* XclPCItem::GetError() const
162 {
163     return (meType == EXC_PCITEM_ERROR) ? &mnError : 0;
164 }
165 
GetBool() const166 const bool* XclPCItem::GetBool() const
167 {
168     return (meType == EXC_PCITEM_BOOL) ? &mbValue : 0;
169 }
170 
GetItemName() const171 const String* XclPCItem::GetItemName() const
172 {
173     //! TODO: use XclImpPCItem::ConvertToText(), if all conversions are available
174     if( EXC_PCITEM_BOOL == this->GetType() )
175     {
176         static String szBool[] = { String::CreateFromAscii("FALSE"), String::CreateFromAscii("TRUE") };
177 
178         if( const bool* pBool = this->GetBool() )
179         {
180             return &(!!*pBool)[szBool];
181         }
182         else
183         {
184             return &0[szBool];
185         }
186     }
187     else
188     {
189         if( this->IsEmpty())
190         {
191             static String aEmptyString( String::EmptyString() );
192             return &aEmptyString;
193         }
194         else
195             return this->GetText();
196     }
197 }
198 
199 
200 // Field settings =============================================================
201 
XclPCFieldInfo()202 XclPCFieldInfo::XclPCFieldInfo() :
203     mnFlags( 0 ),
204     mnGroupChild( 0 ),
205     mnGroupBase( 0 ),
206     mnVisItems( 0 ),
207     mnGroupItems( 0 ),
208     mnBaseItems( 0 ),
209     mnOrigItems( 0 )
210 {
211 }
212 
operator >>(XclImpStream & rStrm,XclPCFieldInfo & rInfo)213 XclImpStream& operator>>( XclImpStream& rStrm, XclPCFieldInfo& rInfo )
214 {
215     rStrm   >> rInfo.mnFlags
216             >> rInfo.mnGroupChild
217             >> rInfo.mnGroupBase
218             >> rInfo.mnVisItems
219             >> rInfo.mnGroupItems
220             >> rInfo.mnBaseItems
221             >> rInfo.mnOrigItems;
222     if( rStrm.GetRecLeft() >= 3 )
223         rInfo.maName = rStrm.ReadUniString();
224     else
225         rInfo.maName.Erase();
226     return rStrm;
227 }
228 
operator <<(XclExpStream & rStrm,const XclPCFieldInfo & rInfo)229 XclExpStream& operator<<( XclExpStream& rStrm, const XclPCFieldInfo& rInfo )
230 {
231     return rStrm
232         << rInfo.mnFlags
233         << rInfo.mnGroupChild
234         << rInfo.mnGroupBase
235         << rInfo.mnVisItems
236         << rInfo.mnGroupItems
237         << rInfo.mnBaseItems
238         << rInfo.mnOrigItems
239         << XclExpString( rInfo.maName );
240 }
241 
242 // Numeric grouping field settings ============================================
243 
XclPCNumGroupInfo()244 XclPCNumGroupInfo::XclPCNumGroupInfo() :
245     mnFlags( EXC_SXNUMGROUP_AUTOMIN | EXC_SXNUMGROUP_AUTOMAX )
246 {
247     SetNumType();
248 }
249 
SetNumType()250 void XclPCNumGroupInfo::SetNumType()
251 {
252     SetXclDataType( EXC_SXNUMGROUP_TYPE_NUM );
253 }
254 
GetScDateType() const255 sal_Int32 XclPCNumGroupInfo::GetScDateType() const
256 {
257     sal_Int32 nScType = 0;
258     switch( GetXclDataType() )
259     {
260         case EXC_SXNUMGROUP_TYPE_SEC:   nScType = ScDPGroupBy::SECONDS;   break;
261         case EXC_SXNUMGROUP_TYPE_MIN:   nScType = ScDPGroupBy::MINUTES;   break;
262         case EXC_SXNUMGROUP_TYPE_HOUR:  nScType = ScDPGroupBy::HOURS;     break;
263         case EXC_SXNUMGROUP_TYPE_DAY:   nScType = ScDPGroupBy::DAYS;      break;
264         case EXC_SXNUMGROUP_TYPE_MONTH: nScType = ScDPGroupBy::MONTHS;    break;
265         case EXC_SXNUMGROUP_TYPE_QUART: nScType = ScDPGroupBy::QUARTERS;  break;
266         case EXC_SXNUMGROUP_TYPE_YEAR:  nScType = ScDPGroupBy::YEARS;     break;
267         default:    DBG_ERROR1( "XclPCNumGroupInfo::GetScDateType - unexpected date type %d", GetXclDataType() );
268     }
269     return nScType;
270 }
271 
SetScDateType(sal_Int32 nScType)272 void XclPCNumGroupInfo::SetScDateType( sal_Int32 nScType )
273 {
274     sal_uInt16 nXclType = EXC_SXNUMGROUP_TYPE_NUM;
275     switch( nScType )
276     {
277         case ScDPGroupBy::SECONDS:    nXclType = EXC_SXNUMGROUP_TYPE_SEC;     break;
278         case ScDPGroupBy::MINUTES:    nXclType = EXC_SXNUMGROUP_TYPE_MIN;     break;
279         case ScDPGroupBy::HOURS:      nXclType = EXC_SXNUMGROUP_TYPE_HOUR;    break;
280         case ScDPGroupBy::DAYS:       nXclType = EXC_SXNUMGROUP_TYPE_DAY;     break;
281         case ScDPGroupBy::MONTHS:     nXclType = EXC_SXNUMGROUP_TYPE_MONTH;   break;
282         case ScDPGroupBy::QUARTERS:   nXclType = EXC_SXNUMGROUP_TYPE_QUART;   break;
283         case ScDPGroupBy::YEARS:      nXclType = EXC_SXNUMGROUP_TYPE_YEAR;    break;
284         default:    DBG_ERROR1( "XclPCNumGroupInfo::SetScDateType - unexpected date type %d", nScType );
285     }
286     SetXclDataType( nXclType );
287 }
288 
GetXclDataType() const289 sal_uInt16 XclPCNumGroupInfo::GetXclDataType() const
290 {
291     return ::extract_value< sal_uInt16 >( mnFlags, 2, 4 );
292 }
293 
SetXclDataType(sal_uInt16 nXclType)294 void XclPCNumGroupInfo::SetXclDataType( sal_uInt16 nXclType )
295 {
296     ::insert_value( mnFlags, nXclType, 2, 4 );
297 }
298 
operator >>(XclImpStream & rStrm,XclPCNumGroupInfo & rInfo)299 XclImpStream& operator>>( XclImpStream& rStrm, XclPCNumGroupInfo& rInfo )
300 {
301     return rStrm >> rInfo.mnFlags;
302 }
303 
operator <<(XclExpStream & rStrm,const XclPCNumGroupInfo & rInfo)304 XclExpStream& operator<<( XclExpStream& rStrm, const XclPCNumGroupInfo& rInfo )
305 {
306     return rStrm << rInfo.mnFlags;
307 }
308 
309 // Base class for pivot cache fields ==========================================
310 
XclPCField(XclPCFieldType eFieldType,sal_uInt16 nFieldIdx)311 XclPCField::XclPCField( XclPCFieldType eFieldType, sal_uInt16 nFieldIdx ) :
312     meFieldType( eFieldType ),
313     mnFieldIdx( nFieldIdx )
314 {
315 }
316 
~XclPCField()317 XclPCField::~XclPCField()
318 {
319 }
320 
IsSupportedField() const321 bool XclPCField::IsSupportedField() const
322 {
323     return (meFieldType != EXC_PCFIELD_CALCED) && (meFieldType != EXC_PCFIELD_UNKNOWN);
324 }
325 
IsStandardField() const326 bool XclPCField::IsStandardField() const
327 {
328     return meFieldType == EXC_PCFIELD_STANDARD;
329 }
330 
331 //UNUSED2008-05  bool XclPCField::IsCalculatedField() const
332 //UNUSED2008-05  {
333 //UNUSED2008-05      return meFieldType == EXC_PCFIELD_CALCED;
334 //UNUSED2008-05  }
335 
IsStdGroupField() const336 bool XclPCField::IsStdGroupField() const
337 {
338     return meFieldType == EXC_PCFIELD_STDGROUP;
339 }
340 
IsNumGroupField() const341 bool XclPCField::IsNumGroupField() const
342 {
343     return meFieldType == EXC_PCFIELD_NUMGROUP;
344 }
345 
IsDateGroupField() const346 bool XclPCField::IsDateGroupField() const
347 {
348     return (meFieldType == EXC_PCFIELD_DATEGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
349 }
350 
IsGroupField() const351 bool XclPCField::IsGroupField() const
352 {
353     return IsStdGroupField() || IsNumGroupField() || IsDateGroupField();
354 }
355 
IsGroupBaseField() const356 bool XclPCField::IsGroupBaseField() const
357 {
358     return ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD );
359 }
360 
IsGroupChildField() const361 bool XclPCField::IsGroupChildField() const
362 {
363     return (meFieldType == EXC_PCFIELD_STDGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
364 }
365 
GetBaseFieldIndex() const366 sal_uInt16 XclPCField::GetBaseFieldIndex() const
367 {
368     return IsGroupChildField() ? maFieldInfo.mnGroupBase : mnFieldIdx;
369 }
370 
HasOrigItems() const371 bool XclPCField::HasOrigItems() const
372 {
373     return IsSupportedField() && ((maFieldInfo.mnOrigItems > 0) || HasPostponedItems());
374 }
375 
HasInlineItems() const376 bool XclPCField::HasInlineItems() const
377 {
378     return (IsStandardField() || IsGroupField()) && ((maFieldInfo.mnGroupItems > 0) || (maFieldInfo.mnOrigItems > 0));
379 }
380 
HasPostponedItems() const381 bool XclPCField::HasPostponedItems() const
382 {
383     return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_POSTPONE );
384 }
385 
Has16BitIndexes() const386 bool XclPCField::Has16BitIndexes() const
387 {
388     return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_16BIT );
389 }
390 
391 // Pivot cache settings =======================================================
392 
393 /** Contains data for a pivot cache (SXDB record). */
XclPCInfo()394 XclPCInfo::XclPCInfo() :
395     mnSrcRecs( 0 ),
396     mnStrmId( 0xFFFF ),
397     mnFlags( EXC_SXDB_DEFAULTFLAGS ),
398     mnBlockRecs( EXC_SXDB_BLOCKRECS ),
399     mnStdFields( 0 ),
400     mnTotalFields( 0 ),
401     mnSrcType( EXC_SXDB_SRC_SHEET )
402 {
403 }
404 
operator >>(XclImpStream & rStrm,XclPCInfo & rInfo)405 XclImpStream& operator>>( XclImpStream& rStrm, XclPCInfo& rInfo )
406 {
407     rStrm   >> rInfo.mnSrcRecs
408             >> rInfo.mnStrmId
409             >> rInfo.mnFlags
410             >> rInfo.mnBlockRecs
411             >> rInfo.mnStdFields
412             >> rInfo.mnTotalFields;
413     rStrm.Ignore( 2 );
414     rStrm   >> rInfo.mnSrcType;
415     rInfo.maUserName = rStrm.ReadUniString();
416     return rStrm;
417 }
418 
operator <<(XclExpStream & rStrm,const XclPCInfo & rInfo)419 XclExpStream& operator<<( XclExpStream& rStrm, const XclPCInfo& rInfo )
420 {
421     return rStrm
422         << rInfo.mnSrcRecs
423         << rInfo.mnStrmId
424         << rInfo.mnFlags
425         << rInfo.mnBlockRecs
426         << rInfo.mnStdFields
427         << rInfo.mnTotalFields
428         << sal_uInt16( 0 )
429         << rInfo.mnSrcType
430         << XclExpString( rInfo.maUserName );
431 }
432 
433 // ============================================================================
434 // Pivot table
435 // ============================================================================
436 
437 // cached name ================================================================
438 
operator >>(XclImpStream & rStrm,XclPTCachedName & rCachedName)439 XclImpStream& operator>>( XclImpStream& rStrm, XclPTCachedName& rCachedName )
440 {
441     sal_uInt16 nStrLen;
442     rStrm >> nStrLen;
443     rCachedName.mbUseCache = nStrLen == EXC_PT_NOSTRING;
444     if( rCachedName.mbUseCache )
445         rCachedName.maName.Erase();
446     else
447         rCachedName.maName = rStrm.ReadUniString( nStrLen );
448     return rStrm;
449 }
450 
operator <<(XclExpStream & rStrm,const XclPTCachedName & rCachedName)451 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTCachedName& rCachedName )
452 {
453     if( rCachedName.mbUseCache )
454         rStrm << EXC_PT_NOSTRING;
455     else
456         rStrm << XclExpString( rCachedName.maName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN );
457     return rStrm;
458 }
459 
460 // ----------------------------------------------------------------------------
461 
GetVisName() const462 const String* XclPTVisNameInfo::GetVisName() const
463 {
464     return HasVisName() ? &maVisName.maName : 0;
465 }
466 
SetVisName(const String & rName)467 void XclPTVisNameInfo::SetVisName( const String& rName )
468 {
469     maVisName.maName = rName;
470     maVisName.mbUseCache = rName.Len() == 0;
471 }
472 
473 // Field item settings ========================================================
474 
XclPTItemInfo()475 XclPTItemInfo::XclPTItemInfo() :
476     mnType( EXC_SXVI_TYPE_DATA ),
477     mnFlags( EXC_SXVI_DEFAULTFLAGS ),
478     mnCacheIdx( EXC_SXVI_DEFAULT_CACHE )
479 {
480 }
481 
operator >>(XclImpStream & rStrm,XclPTItemInfo & rInfo)482 XclImpStream& operator>>( XclImpStream& rStrm, XclPTItemInfo& rInfo )
483 {
484     return rStrm
485         >> rInfo.mnType
486         >> rInfo.mnFlags
487         >> rInfo.mnCacheIdx
488         >> rInfo.maVisName;
489 }
490 
operator <<(XclExpStream & rStrm,const XclPTItemInfo & rInfo)491 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTItemInfo& rInfo )
492 {
493     return rStrm
494         << rInfo.mnType
495         << rInfo.mnFlags
496         << rInfo.mnCacheIdx
497         << rInfo.maVisName;
498 }
499 
500 // General field settings =====================================================
501 
XclPTFieldInfo()502 XclPTFieldInfo::XclPTFieldInfo() :
503     mnAxes( EXC_SXVD_AXIS_NONE ),
504     mnSubtCount( 1 ),
505     mnSubtotals( EXC_SXVD_SUBT_DEFAULT ),
506     mnItemCount( 0 ),
507     mnCacheIdx( EXC_SXVD_DEFAULT_CACHE )
508 {
509 }
510 
GetApiOrient(sal_uInt16 nMask) const511 DataPilotFieldOrientation XclPTFieldInfo::GetApiOrient( sal_uInt16 nMask ) const
512 {
513     using namespace ::com::sun::star::sheet;
514     DataPilotFieldOrientation eOrient = DataPilotFieldOrientation_HIDDEN;
515     sal_uInt16 nUsedAxes = mnAxes & nMask;
516     if( nUsedAxes & EXC_SXVD_AXIS_ROW )
517         eOrient = DataPilotFieldOrientation_ROW;
518     else if( nUsedAxes & EXC_SXVD_AXIS_COL )
519         eOrient = DataPilotFieldOrientation_COLUMN;
520     else if( nUsedAxes & EXC_SXVD_AXIS_PAGE )
521         eOrient = DataPilotFieldOrientation_PAGE;
522     else if( nUsedAxes & EXC_SXVD_AXIS_DATA )
523         eOrient = DataPilotFieldOrientation_DATA;
524     return eOrient;
525 }
526 
AddApiOrient(DataPilotFieldOrientation eOrient)527 void XclPTFieldInfo::AddApiOrient( DataPilotFieldOrientation eOrient )
528 {
529     using namespace ::com::sun::star::sheet;
530     switch( eOrient )
531     {
532         case DataPilotFieldOrientation_ROW:     mnAxes |= EXC_SXVD_AXIS_ROW;    break;
533         case DataPilotFieldOrientation_COLUMN:  mnAxes |= EXC_SXVD_AXIS_COL;    break;
534         case DataPilotFieldOrientation_PAGE:    mnAxes |= EXC_SXVD_AXIS_PAGE;   break;
535         case DataPilotFieldOrientation_DATA:    mnAxes |= EXC_SXVD_AXIS_DATA;   break;
536         default:;
537     }
538 }
539 
540 //! TODO: should be a Sequence<GeneralFunction> in ScDPSaveData
GetSubtotals(XclPTSubtotalVec & rSubtotals) const541 void XclPTFieldInfo::GetSubtotals( XclPTSubtotalVec& rSubtotals ) const
542 {
543     rSubtotals.clear();
544     rSubtotals.reserve( 16 );
545 
546     using namespace ::com::sun::star::sheet;
547     if( mnSubtotals & EXC_SXVD_SUBT_DEFAULT )   rSubtotals.push_back( GeneralFunction_AUTO );
548     if( mnSubtotals & EXC_SXVD_SUBT_SUM )       rSubtotals.push_back( GeneralFunction_SUM );
549     if( mnSubtotals & EXC_SXVD_SUBT_COUNT )     rSubtotals.push_back( GeneralFunction_COUNT );
550     if( mnSubtotals & EXC_SXVD_SUBT_AVERAGE )   rSubtotals.push_back( GeneralFunction_AVERAGE );
551     if( mnSubtotals & EXC_SXVD_SUBT_MAX )       rSubtotals.push_back( GeneralFunction_MAX );
552     if( mnSubtotals & EXC_SXVD_SUBT_MIN )       rSubtotals.push_back( GeneralFunction_MIN );
553     if( mnSubtotals & EXC_SXVD_SUBT_PROD )      rSubtotals.push_back( GeneralFunction_PRODUCT );
554     if( mnSubtotals & EXC_SXVD_SUBT_COUNTNUM )  rSubtotals.push_back( GeneralFunction_COUNTNUMS );
555     if( mnSubtotals & EXC_SXVD_SUBT_STDDEV )    rSubtotals.push_back( GeneralFunction_STDEV );
556     if( mnSubtotals & EXC_SXVD_SUBT_STDDEVP )   rSubtotals.push_back( GeneralFunction_STDEVP );
557     if( mnSubtotals & EXC_SXVD_SUBT_VAR )       rSubtotals.push_back( GeneralFunction_VAR );
558     if( mnSubtotals & EXC_SXVD_SUBT_VARP )      rSubtotals.push_back( GeneralFunction_VARP );
559 }
560 
SetSubtotals(const XclPTSubtotalVec & rSubtotals)561 void XclPTFieldInfo::SetSubtotals( const XclPTSubtotalVec& rSubtotals )
562 {
563     mnSubtotals = EXC_SXVD_SUBT_NONE;
564     using namespace ::com::sun::star::sheet;
565     for( XclPTSubtotalVec::const_iterator aIt = rSubtotals.begin(), aEnd = rSubtotals.end(); aIt != aEnd; ++aIt )
566     {
567         switch( *aIt )
568         {
569             case GeneralFunction_AUTO:      mnSubtotals |= EXC_SXVD_SUBT_DEFAULT;   break;
570             case GeneralFunction_SUM:       mnSubtotals |= EXC_SXVD_SUBT_SUM;       break;
571             case GeneralFunction_COUNT:     mnSubtotals |= EXC_SXVD_SUBT_COUNT;     break;
572             case GeneralFunction_AVERAGE:   mnSubtotals |= EXC_SXVD_SUBT_AVERAGE;   break;
573             case GeneralFunction_MAX:       mnSubtotals |= EXC_SXVD_SUBT_MAX;       break;
574             case GeneralFunction_MIN:       mnSubtotals |= EXC_SXVD_SUBT_MIN;       break;
575             case GeneralFunction_PRODUCT:   mnSubtotals |= EXC_SXVD_SUBT_PROD;      break;
576             case GeneralFunction_COUNTNUMS: mnSubtotals |= EXC_SXVD_SUBT_COUNTNUM;  break;
577             case GeneralFunction_STDEV:     mnSubtotals |= EXC_SXVD_SUBT_STDDEV;    break;
578             case GeneralFunction_STDEVP:    mnSubtotals |= EXC_SXVD_SUBT_STDDEVP;   break;
579             case GeneralFunction_VAR:       mnSubtotals |= EXC_SXVD_SUBT_VAR;       break;
580             case GeneralFunction_VARP:      mnSubtotals |= EXC_SXVD_SUBT_VARP;      break;
581         }
582     }
583 
584     mnSubtCount = 0;
585     for( sal_uInt16 nMask = 0x8000; nMask; nMask >>= 1 )
586         if( mnSubtotals & nMask )
587             ++mnSubtCount;
588 }
589 
operator >>(XclImpStream & rStrm,XclPTFieldInfo & rInfo)590 XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldInfo& rInfo )
591 {
592     // rInfo.mnCacheIdx is not part of the SXVD record
593     return rStrm
594         >> rInfo.mnAxes
595         >> rInfo.mnSubtCount
596         >> rInfo.mnSubtotals
597         >> rInfo.mnItemCount
598         >> rInfo.maVisName;
599 }
600 
operator <<(XclExpStream & rStrm,const XclPTFieldInfo & rInfo)601 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo )
602 {
603     // rInfo.mnCacheIdx is not part of the SXVD record
604     return rStrm
605         << rInfo.mnAxes
606         << rInfo.mnSubtCount
607         << rInfo.mnSubtotals
608         << rInfo.mnItemCount
609         << rInfo.maVisName;
610 }
611 
612 // Extended field settings ====================================================
613 
XclPTFieldExtInfo()614 XclPTFieldExtInfo::XclPTFieldExtInfo() :
615     mnFlags( EXC_SXVDEX_DEFAULTFLAGS ),
616     mnSortField( EXC_SXVDEX_SORT_OWN ),
617     mnShowField( EXC_SXVDEX_SHOW_NONE ),
618     mnNumFmt(0),
619     mpFieldTotalName(NULL)
620 {
621 }
622 
GetApiSortMode() const623 sal_Int32 XclPTFieldExtInfo::GetApiSortMode() const
624 {
625     sal_Int32 nSortMode = ScDPSortMode::MANUAL;
626     if( ::get_flag( mnFlags, EXC_SXVDEX_SORT ) )
627         nSortMode = (mnSortField == EXC_SXVDEX_SORT_OWN) ? ScDPSortMode::NAME : ScDPSortMode::DATA;
628     return nSortMode;
629 }
630 
SetApiSortMode(sal_Int32 nSortMode)631 void XclPTFieldExtInfo::SetApiSortMode( sal_Int32 nSortMode )
632 {
633     bool bSort = (nSortMode == ScDPSortMode::NAME) || (nSortMode == ScDPSortMode::DATA);
634     ::set_flag( mnFlags, EXC_SXVDEX_SORT, bSort );
635     if( nSortMode == ScDPSortMode::NAME )
636         mnSortField = EXC_SXVDEX_SORT_OWN;  // otherwise sort field has to be set by caller
637 }
638 
GetApiAutoShowMode() const639 sal_Int32 XclPTFieldExtInfo::GetApiAutoShowMode() const
640 {
641     return ::get_flagvalue( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC,
642         ScDPShowItemsMode::FROM_TOP, ScDPShowItemsMode::FROM_BOTTOM );
643 }
644 
SetApiAutoShowMode(sal_Int32 nShowMode)645 void XclPTFieldExtInfo::SetApiAutoShowMode( sal_Int32 nShowMode )
646 {
647     ::set_flag( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC, nShowMode == ScDPShowItemsMode::FROM_TOP );
648 }
649 
GetApiAutoShowCount() const650 sal_Int32 XclPTFieldExtInfo::GetApiAutoShowCount() const
651 {
652     return ::extract_value< sal_Int32 >( mnFlags, 24, 8 );
653 }
654 
SetApiAutoShowCount(sal_Int32 nShowCount)655 void XclPTFieldExtInfo::SetApiAutoShowCount( sal_Int32 nShowCount )
656 {
657     ::insert_value( mnFlags, limit_cast< sal_uInt8 >( nShowCount ), 24, 8 );
658 }
659 
GetApiLayoutMode() const660 sal_Int32 XclPTFieldExtInfo::GetApiLayoutMode() const
661 {
662     sal_Int32 nLayoutMode = ScDPLayoutMode::TABULAR_LAYOUT;
663     if( ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT ) )
664         nLayoutMode = ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP ) ?
665             ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP : ScDPLayoutMode::OUTLINE_SUBTOTALS_BOTTOM;
666     return nLayoutMode;
667 }
668 
SetApiLayoutMode(sal_Int32 nLayoutMode)669 void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode )
670 {
671     ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT, nLayoutMode != ScDPLayoutMode::TABULAR_LAYOUT );
672     ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP, nLayoutMode == ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP );
673 }
674 
operator >>(XclImpStream & rStrm,XclPTFieldExtInfo & rInfo)675 XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo )
676 {
677     sal_uInt8 nNameLen = 0;
678     rStrm >> rInfo.mnFlags
679           >> rInfo.mnSortField
680           >> rInfo.mnShowField
681           >> rInfo.mnNumFmt
682           >> nNameLen;
683 
684     rStrm.Ignore(10);
685     if (nNameLen != 0xFF)
686         // Custom field total name is used.  Pick it up.
687         rInfo.mpFieldTotalName.reset(new rtl::OUString(rStrm.ReadUniString(nNameLen, 0)));
688 
689     return rStrm;
690 }
691 
operator <<(XclExpStream & rStrm,const XclPTFieldExtInfo & rInfo)692 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
693 {
694     rStrm   << rInfo.mnFlags
695             << rInfo.mnSortField
696             << rInfo.mnShowField
697             << EXC_SXVDEX_FORMAT_NONE;
698 
699     if (rInfo.mpFieldTotalName.get() && rInfo.mpFieldTotalName->getLength() > 0)
700     {
701         rtl::OUString aFinalName = *rInfo.mpFieldTotalName;
702         if (aFinalName.getLength() >= 254)
703             aFinalName = aFinalName.copy(0, 254);
704         sal_uInt8 nNameLen = static_cast<sal_uInt8>(aFinalName.getLength());
705         rStrm << nNameLen;
706         rStrm.WriteZeroBytes(10);
707         rStrm << XclExpString(aFinalName, EXC_STR_NOHEADER);
708     }
709     else
710     {
711         rStrm << sal_uInt16(0xFFFF);
712         rStrm.WriteZeroBytes(8);
713     }
714     return rStrm;
715 }
716 
717 // Page field settings ========================================================
718 
XclPTPageFieldInfo()719 XclPTPageFieldInfo::XclPTPageFieldInfo() :
720     mnField( 0 ),
721     mnSelItem( EXC_SXPI_ALLITEMS ),
722     mnObjId( 0xFFFF )
723 {
724 }
725 
operator >>(XclImpStream & rStrm,XclPTPageFieldInfo & rInfo)726 XclImpStream& operator>>( XclImpStream& rStrm, XclPTPageFieldInfo& rInfo )
727 {
728     return rStrm
729         >> rInfo.mnField
730         >> rInfo.mnSelItem
731         >> rInfo.mnObjId;
732 }
733 
operator <<(XclExpStream & rStrm,const XclPTPageFieldInfo & rInfo)734 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTPageFieldInfo& rInfo )
735 {
736     return rStrm
737         << rInfo.mnField
738         << rInfo.mnSelItem
739         << rInfo.mnObjId;
740 }
741 
742 // Data field settings ========================================================
743 
XclPTDataFieldInfo()744 XclPTDataFieldInfo::XclPTDataFieldInfo() :
745     mnField( 0 ),
746     mnAggFunc( EXC_SXDI_FUNC_SUM ),
747     mnRefType( EXC_SXDI_REF_NORMAL ),
748     mnRefField( 0 ),
749     mnRefItem( 0 ),
750     mnNumFmt( 0 )
751 {
752 }
753 
GetApiAggFunc() const754 GeneralFunction XclPTDataFieldInfo::GetApiAggFunc() const
755 {
756     using namespace ::com::sun::star::sheet;
757     GeneralFunction eAggFunc;
758     switch( mnAggFunc )
759     {
760         case EXC_SXDI_FUNC_SUM:         eAggFunc = GeneralFunction_SUM;         break;
761         case EXC_SXDI_FUNC_COUNT:       eAggFunc = GeneralFunction_COUNT;       break;
762         case EXC_SXDI_FUNC_AVERAGE:     eAggFunc = GeneralFunction_AVERAGE;     break;
763         case EXC_SXDI_FUNC_MAX:         eAggFunc = GeneralFunction_MAX;         break;
764         case EXC_SXDI_FUNC_MIN:         eAggFunc = GeneralFunction_MIN;         break;
765         case EXC_SXDI_FUNC_PRODUCT:     eAggFunc = GeneralFunction_PRODUCT;     break;
766         case EXC_SXDI_FUNC_COUNTNUM:    eAggFunc = GeneralFunction_COUNTNUMS;   break;
767         case EXC_SXDI_FUNC_STDDEV:      eAggFunc = GeneralFunction_STDEV;       break;
768         case EXC_SXDI_FUNC_STDDEVP:     eAggFunc = GeneralFunction_STDEVP;      break;
769         case EXC_SXDI_FUNC_VAR:         eAggFunc = GeneralFunction_VAR;         break;
770         case EXC_SXDI_FUNC_VARP:        eAggFunc = GeneralFunction_VARP;        break;
771         default:                        eAggFunc = GeneralFunction_SUM;
772     }
773     return eAggFunc;
774 }
775 
SetApiAggFunc(GeneralFunction eAggFunc)776 void XclPTDataFieldInfo::SetApiAggFunc( GeneralFunction eAggFunc )
777 {
778     using namespace ::com::sun::star::sheet;
779     switch( eAggFunc )
780     {
781         case GeneralFunction_SUM:       mnAggFunc = EXC_SXDI_FUNC_SUM;      break;
782         case GeneralFunction_COUNT:     mnAggFunc = EXC_SXDI_FUNC_COUNT;    break;
783         case GeneralFunction_AVERAGE:   mnAggFunc = EXC_SXDI_FUNC_AVERAGE;  break;
784         case GeneralFunction_MAX:       mnAggFunc = EXC_SXDI_FUNC_MAX;      break;
785         case GeneralFunction_MIN:       mnAggFunc = EXC_SXDI_FUNC_MIN;      break;
786         case GeneralFunction_PRODUCT:   mnAggFunc = EXC_SXDI_FUNC_PRODUCT;  break;
787         case GeneralFunction_COUNTNUMS: mnAggFunc = EXC_SXDI_FUNC_COUNTNUM; break;
788         case GeneralFunction_STDEV:     mnAggFunc = EXC_SXDI_FUNC_STDDEV;   break;
789         case GeneralFunction_STDEVP:    mnAggFunc = EXC_SXDI_FUNC_STDDEVP;  break;
790         case GeneralFunction_VAR:       mnAggFunc = EXC_SXDI_FUNC_VAR;      break;
791         case GeneralFunction_VARP:      mnAggFunc = EXC_SXDI_FUNC_VARP;     break;
792         default:                        mnAggFunc = EXC_SXDI_FUNC_SUM;
793     }
794 }
795 
GetApiRefType() const796 sal_Int32 XclPTDataFieldInfo::GetApiRefType() const
797 {
798     namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
799     sal_Int32 nRefType;
800     switch( mnRefType )
801     {
802         case EXC_SXDI_REF_DIFF:         nRefType = ScDPRefType::ITEM_DIFFERENCE;            break;
803         case EXC_SXDI_REF_PERC:         nRefType = ScDPRefType::ITEM_PERCENTAGE;            break;
804         case EXC_SXDI_REF_PERC_DIFF:    nRefType = ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE; break;
805         case EXC_SXDI_REF_RUN_TOTAL:    nRefType = ScDPRefType::RUNNING_TOTAL;              break;
806         case EXC_SXDI_REF_PERC_ROW:     nRefType = ScDPRefType::ROW_PERCENTAGE;             break;
807         case EXC_SXDI_REF_PERC_COL:     nRefType = ScDPRefType::COLUMN_PERCENTAGE;          break;
808         case EXC_SXDI_REF_PERC_TOTAL:   nRefType = ScDPRefType::TOTAL_PERCENTAGE;           break;
809         case EXC_SXDI_REF_INDEX:        nRefType = ScDPRefType::INDEX;                      break;
810         default:                        nRefType = ScDPRefType::NONE;
811     }
812     return nRefType;
813 }
814 
SetApiRefType(sal_Int32 nRefType)815 void XclPTDataFieldInfo::SetApiRefType( sal_Int32 nRefType )
816 {
817     namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
818     switch( nRefType )
819     {
820         case ScDPRefType::ITEM_DIFFERENCE:              mnRefType = EXC_SXDI_REF_DIFF;      break;
821         case ScDPRefType::ITEM_PERCENTAGE:              mnRefType = EXC_SXDI_REF_PERC;      break;
822         case ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE:   mnRefType = EXC_SXDI_REF_PERC_DIFF; break;
823         case ScDPRefType::RUNNING_TOTAL:                mnRefType = EXC_SXDI_REF_RUN_TOTAL; break;
824         case ScDPRefType::ROW_PERCENTAGE:               mnRefType = EXC_SXDI_REF_PERC_ROW;  break;
825         case ScDPRefType::COLUMN_PERCENTAGE:            mnRefType = EXC_SXDI_REF_PERC_COL;  break;
826         case ScDPRefType::TOTAL_PERCENTAGE:             mnRefType = EXC_SXDI_REF_PERC_TOTAL;break;
827         case ScDPRefType::INDEX:                        mnRefType = EXC_SXDI_REF_INDEX;     break;
828         default:                                        mnRefType = EXC_SXDI_REF_NORMAL;
829     }
830 }
831 
GetApiRefItemType() const832 sal_Int32 XclPTDataFieldInfo::GetApiRefItemType() const
833 {
834     sal_Int32 nRefItemType;
835     switch( mnRefItem )
836     {
837         case EXC_SXDI_PREVITEM: nRefItemType = ScDPRefItemType::PREVIOUS;   break;
838         case EXC_SXDI_NEXTITEM: nRefItemType = ScDPRefItemType::NEXT;       break;
839         default:                nRefItemType = ScDPRefItemType::NAMED;
840     }
841     return nRefItemType;
842 }
843 
SetApiRefItemType(sal_Int32 nRefItemType)844 void XclPTDataFieldInfo::SetApiRefItemType( sal_Int32 nRefItemType )
845 {
846     switch( nRefItemType )
847     {
848         case ScDPRefItemType::PREVIOUS: mnRefItem = EXC_SXDI_PREVITEM;  break;
849         case ScDPRefItemType::NEXT:     mnRefItem = EXC_SXDI_NEXTITEM;  break;
850         // nothing for named item reference
851     }
852 }
853 
operator >>(XclImpStream & rStrm,XclPTDataFieldInfo & rInfo)854 XclImpStream& operator>>( XclImpStream& rStrm, XclPTDataFieldInfo& rInfo )
855 {
856     return rStrm
857         >> rInfo.mnField
858         >> rInfo.mnAggFunc
859         >> rInfo.mnRefType
860         >> rInfo.mnRefField
861         >> rInfo.mnRefItem
862         >> rInfo.mnNumFmt
863         >> rInfo.maVisName;
864 }
865 
operator <<(XclExpStream & rStrm,const XclPTDataFieldInfo & rInfo)866 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTDataFieldInfo& rInfo )
867 {
868     return rStrm
869         << rInfo.mnField
870         << rInfo.mnAggFunc
871         << rInfo.mnRefType
872         << rInfo.mnRefField
873         << rInfo.mnRefItem
874         << rInfo.mnNumFmt
875         << rInfo.maVisName;
876 }
877 
878 // Pivot table settings =======================================================
879 
XclPTInfo()880 XclPTInfo::XclPTInfo() :
881     mnFirstHeadRow( 0 ),
882     mnCacheIdx( 0xFFFF ),
883     mnDataAxis( EXC_SXVD_AXIS_NONE ),
884     mnDataPos( EXC_SXVIEW_DATALAST ),
885     mnFields( 0 ),
886     mnRowFields( 0 ),
887     mnColFields( 0 ),
888     mnPageFields( 0 ),
889     mnDataFields( 0 ),
890     mnDataRows( 0 ),
891     mnDataCols( 0 ),
892     mnFlags( EXC_SXVIEW_DEFAULTFLAGS ),
893     mnAutoFmtIdx( EXC_SXVIEW_AUTOFMT )
894 {
895 }
896 
operator >>(XclImpStream & rStrm,XclPTInfo & rInfo)897 XclImpStream& operator>>( XclImpStream& rStrm, XclPTInfo& rInfo )
898 {
899     sal_uInt16 nTabLen, nDataLen;
900 
901     rStrm   >> rInfo.maOutXclRange
902             >> rInfo.mnFirstHeadRow
903             >> rInfo.maDataXclPos
904             >> rInfo.mnCacheIdx;
905     rStrm.Ignore( 2 );
906     rStrm   >> rInfo.mnDataAxis >> rInfo.mnDataPos
907             >> rInfo.mnFields
908             >> rInfo.mnRowFields >> rInfo.mnColFields
909             >> rInfo.mnPageFields >> rInfo.mnDataFields
910             >> rInfo.mnDataRows >> rInfo.mnDataCols
911             >> rInfo.mnFlags
912             >> rInfo.mnAutoFmtIdx
913             >> nTabLen >> nDataLen;
914     rInfo.maTableName = rStrm.ReadUniString( nTabLen );
915     rInfo.maDataName = rStrm.ReadUniString( nDataLen );
916     return rStrm;
917 }
918 
operator <<(XclExpStream & rStrm,const XclPTInfo & rInfo)919 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTInfo& rInfo )
920 {
921     XclExpString aXclTableName( rInfo.maTableName );
922     XclExpString aXclDataName( rInfo.maDataName );
923 
924     rStrm   << rInfo.maOutXclRange
925             << rInfo.mnFirstHeadRow
926             << rInfo.maDataXclPos
927             << rInfo.mnCacheIdx
928             << sal_uInt16( 0 )
929             << rInfo.mnDataAxis << rInfo.mnDataPos
930             << rInfo.mnFields
931             << rInfo.mnRowFields << rInfo.mnColFields
932             << rInfo.mnPageFields << rInfo.mnDataFields
933             << rInfo.mnDataRows << rInfo.mnDataCols
934             << rInfo.mnFlags
935             << rInfo.mnAutoFmtIdx
936             << aXclTableName.Len() << aXclDataName.Len();
937     aXclTableName.WriteFlagField( rStrm );
938     aXclTableName.WriteBuffer( rStrm );
939     aXclDataName.WriteFlagField( rStrm );
940     aXclDataName.WriteBuffer( rStrm );
941     return rStrm;
942 }
943 
944 // Extended pivot table settings ==============================================
945 
XclPTExtInfo()946 XclPTExtInfo::XclPTExtInfo() :
947     mnSxformulaRecs( 0 ),
948     mnSxselectRecs( 0 ),
949     mnPagePerRow( 0 ),
950     mnPagePerCol( 0 ),
951     mnFlags( EXC_SXEX_DEFAULTFLAGS )
952 {
953 }
954 
operator >>(XclImpStream & rStrm,XclPTExtInfo & rInfo)955 XclImpStream& operator>>( XclImpStream& rStrm, XclPTExtInfo& rInfo )
956 {
957     rStrm >> rInfo.mnSxformulaRecs;
958     rStrm.Ignore( 6 );
959     return rStrm
960         >> rInfo.mnSxselectRecs
961         >> rInfo.mnPagePerRow
962         >> rInfo.mnPagePerCol
963         >> rInfo.mnFlags;
964 }
965 
operator <<(XclExpStream & rStrm,const XclPTExtInfo & rInfo)966 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo )
967 {
968     return rStrm
969         << rInfo.mnSxformulaRecs
970         << EXC_PT_NOSTRING              // length of alt. error text
971         << EXC_PT_NOSTRING              // length of alt. empty text
972         << EXC_PT_NOSTRING              // length of tag
973         << rInfo.mnSxselectRecs
974         << rInfo.mnPagePerRow
975         << rInfo.mnPagePerCol
976         << rInfo.mnFlags
977         << EXC_PT_NOSTRING              // length of page field style name
978         << EXC_PT_NOSTRING              // length of table style name
979         << EXC_PT_NOSTRING;             // length of vacate style name
980 }
981 
982 // ============================================================================
983 
984 // Pivot table autoformat settings ============================================
985 
986 /**
987 classic     : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
988 default     : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
989 report01    : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00
990 report02    : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00
991 report03    : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00
992 report04    : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00
993 report05    : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00
994 report06    : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00
995 report07    : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00
996 report08    : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00
997 report09    : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00
998 report10    : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00
999 table01     : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00
1000 table02     : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00
1001 table03     : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00
1002 table04     : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00
1003 table05     : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00
1004 table06     : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00
1005 table07     : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00
1006 table08     : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00
1007 table09     : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00
1008 table10     : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00
1009 none        : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00
1010 **/
1011 
XclPTViewEx9Info()1012 XclPTViewEx9Info::XclPTViewEx9Info() :
1013     mbReport( 0 ),
1014     mnAutoFormat( 0 ),
1015     mnGridLayout( 0x10 )
1016 {
1017 }
1018 
Init(const ScDPObject & rDPObj)1019 void XclPTViewEx9Info::Init( const ScDPObject& rDPObj )
1020 {
1021     if( rDPObj.GetHeaderLayout() )
1022     {
1023         mbReport     = 0;
1024         mnAutoFormat = 1;
1025         mnGridLayout = 0;
1026     }
1027     else
1028     {
1029         // Report1 for now
1030         // TODO : sync with autoformat indices
1031         mbReport     = 2;
1032         mnAutoFormat = 1;
1033         mnGridLayout = 0x10;
1034     }
1035 
1036     const ScDPSaveData* pData = rDPObj.GetSaveData();
1037     if (pData)
1038     {
1039         const rtl::OUString* pGrandTotal = pData->GetGrandTotalName();
1040         if (pGrandTotal)
1041             maGrandTotalName = *pGrandTotal;
1042     }
1043 }
1044 
operator >>(XclImpStream & rStrm,XclPTViewEx9Info & rInfo)1045 XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo )
1046 {
1047     rStrm.Ignore( 2 );
1048     rStrm >> rInfo.mbReport;            /// 2 for report* fmts ?
1049     rStrm.Ignore( 6 );
1050     rStrm >> rInfo.mnAutoFormat >> rInfo.mnGridLayout;
1051     rInfo.maGrandTotalName = rStrm.ReadUniString();
1052     return rStrm;
1053 }
1054 
operator <<(XclExpStream & rStrm,const XclPTViewEx9Info & rInfo)1055 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo )
1056 {
1057     return rStrm
1058         << EXC_PT_AUTOFMT_HEADER
1059         << rInfo.mbReport
1060         << EXC_PT_AUTOFMT_ZERO
1061         << EXC_PT_AUTOFMT_FLAGS
1062         << rInfo.mnAutoFormat
1063         << rInfo.mnGridLayout
1064         << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN);
1065 }
1066 
1067