xref: /aoo4110/main/sc/source/filter/excel/xlpivot.cxx (revision b1cdbd2c)
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_sc.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     return NULL;
199 }
200 
201 
202 // Field settings =============================================================
203 
XclPCFieldInfo()204 XclPCFieldInfo::XclPCFieldInfo() :
205     mnFlags( 0 ),
206     mnGroupChild( 0 ),
207     mnGroupBase( 0 ),
208     mnVisItems( 0 ),
209     mnGroupItems( 0 ),
210     mnBaseItems( 0 ),
211     mnOrigItems( 0 )
212 {
213 }
214 
operator >>(XclImpStream & rStrm,XclPCFieldInfo & rInfo)215 XclImpStream& operator>>( XclImpStream& rStrm, XclPCFieldInfo& rInfo )
216 {
217     rStrm   >> rInfo.mnFlags
218             >> rInfo.mnGroupChild
219             >> rInfo.mnGroupBase
220             >> rInfo.mnVisItems
221             >> rInfo.mnGroupItems
222             >> rInfo.mnBaseItems
223             >> rInfo.mnOrigItems;
224     if( rStrm.GetRecLeft() >= 3 )
225         rInfo.maName = rStrm.ReadUniString();
226     else
227         rInfo.maName.Erase();
228     return rStrm;
229 }
230 
operator <<(XclExpStream & rStrm,const XclPCFieldInfo & rInfo)231 XclExpStream& operator<<( XclExpStream& rStrm, const XclPCFieldInfo& rInfo )
232 {
233     return rStrm
234         << rInfo.mnFlags
235         << rInfo.mnGroupChild
236         << rInfo.mnGroupBase
237         << rInfo.mnVisItems
238         << rInfo.mnGroupItems
239         << rInfo.mnBaseItems
240         << rInfo.mnOrigItems
241         << XclExpString( rInfo.maName );
242 }
243 
244 // Numeric grouping field settings ============================================
245 
XclPCNumGroupInfo()246 XclPCNumGroupInfo::XclPCNumGroupInfo() :
247     mnFlags( EXC_SXNUMGROUP_AUTOMIN | EXC_SXNUMGROUP_AUTOMAX )
248 {
249     SetNumType();
250 }
251 
SetNumType()252 void XclPCNumGroupInfo::SetNumType()
253 {
254     SetXclDataType( EXC_SXNUMGROUP_TYPE_NUM );
255 }
256 
GetScDateType() const257 sal_Int32 XclPCNumGroupInfo::GetScDateType() const
258 {
259     sal_Int32 nScType = 0;
260     switch( GetXclDataType() )
261     {
262         case EXC_SXNUMGROUP_TYPE_SEC:   nScType = ScDPGroupBy::SECONDS;   break;
263         case EXC_SXNUMGROUP_TYPE_MIN:   nScType = ScDPGroupBy::MINUTES;   break;
264         case EXC_SXNUMGROUP_TYPE_HOUR:  nScType = ScDPGroupBy::HOURS;     break;
265         case EXC_SXNUMGROUP_TYPE_DAY:   nScType = ScDPGroupBy::DAYS;      break;
266         case EXC_SXNUMGROUP_TYPE_MONTH: nScType = ScDPGroupBy::MONTHS;    break;
267         case EXC_SXNUMGROUP_TYPE_QUART: nScType = ScDPGroupBy::QUARTERS;  break;
268         case EXC_SXNUMGROUP_TYPE_YEAR:  nScType = ScDPGroupBy::YEARS;     break;
269         default:    DBG_ERROR1( "XclPCNumGroupInfo::GetScDateType - unexpected date type %d", GetXclDataType() );
270     }
271     return nScType;
272 }
273 
SetScDateType(sal_Int32 nScType)274 void XclPCNumGroupInfo::SetScDateType( sal_Int32 nScType )
275 {
276     sal_uInt16 nXclType = EXC_SXNUMGROUP_TYPE_NUM;
277     switch( nScType )
278     {
279         case ScDPGroupBy::SECONDS:    nXclType = EXC_SXNUMGROUP_TYPE_SEC;     break;
280         case ScDPGroupBy::MINUTES:    nXclType = EXC_SXNUMGROUP_TYPE_MIN;     break;
281         case ScDPGroupBy::HOURS:      nXclType = EXC_SXNUMGROUP_TYPE_HOUR;    break;
282         case ScDPGroupBy::DAYS:       nXclType = EXC_SXNUMGROUP_TYPE_DAY;     break;
283         case ScDPGroupBy::MONTHS:     nXclType = EXC_SXNUMGROUP_TYPE_MONTH;   break;
284         case ScDPGroupBy::QUARTERS:   nXclType = EXC_SXNUMGROUP_TYPE_QUART;   break;
285         case ScDPGroupBy::YEARS:      nXclType = EXC_SXNUMGROUP_TYPE_YEAR;    break;
286         default:    DBG_ERROR1( "XclPCNumGroupInfo::SetScDateType - unexpected date type %d", nScType );
287     }
288     SetXclDataType( nXclType );
289 }
290 
GetXclDataType() const291 sal_uInt16 XclPCNumGroupInfo::GetXclDataType() const
292 {
293     return ::extract_value< sal_uInt16 >( mnFlags, 2, 4 );
294 }
295 
SetXclDataType(sal_uInt16 nXclType)296 void XclPCNumGroupInfo::SetXclDataType( sal_uInt16 nXclType )
297 {
298     ::insert_value( mnFlags, nXclType, 2, 4 );
299 }
300 
operator >>(XclImpStream & rStrm,XclPCNumGroupInfo & rInfo)301 XclImpStream& operator>>( XclImpStream& rStrm, XclPCNumGroupInfo& rInfo )
302 {
303     return rStrm >> rInfo.mnFlags;
304 }
305 
operator <<(XclExpStream & rStrm,const XclPCNumGroupInfo & rInfo)306 XclExpStream& operator<<( XclExpStream& rStrm, const XclPCNumGroupInfo& rInfo )
307 {
308     return rStrm << rInfo.mnFlags;
309 }
310 
311 // Base class for pivot cache fields ==========================================
312 
XclPCField(XclPCFieldType eFieldType,sal_uInt16 nFieldIdx)313 XclPCField::XclPCField( XclPCFieldType eFieldType, sal_uInt16 nFieldIdx ) :
314     meFieldType( eFieldType ),
315     mnFieldIdx( nFieldIdx )
316 {
317 }
318 
~XclPCField()319 XclPCField::~XclPCField()
320 {
321 }
322 
IsSupportedField() const323 bool XclPCField::IsSupportedField() const
324 {
325     return (meFieldType != EXC_PCFIELD_CALCED) && (meFieldType != EXC_PCFIELD_UNKNOWN);
326 }
327 
IsStandardField() const328 bool XclPCField::IsStandardField() const
329 {
330     return meFieldType == EXC_PCFIELD_STANDARD;
331 }
332 
333 //UNUSED2008-05  bool XclPCField::IsCalculatedField() const
334 //UNUSED2008-05  {
335 //UNUSED2008-05      return meFieldType == EXC_PCFIELD_CALCED;
336 //UNUSED2008-05  }
337 
IsStdGroupField() const338 bool XclPCField::IsStdGroupField() const
339 {
340     return meFieldType == EXC_PCFIELD_STDGROUP;
341 }
342 
IsNumGroupField() const343 bool XclPCField::IsNumGroupField() const
344 {
345     return meFieldType == EXC_PCFIELD_NUMGROUP;
346 }
347 
IsDateGroupField() const348 bool XclPCField::IsDateGroupField() const
349 {
350     return (meFieldType == EXC_PCFIELD_DATEGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
351 }
352 
IsGroupField() const353 bool XclPCField::IsGroupField() const
354 {
355     return IsStdGroupField() || IsNumGroupField() || IsDateGroupField();
356 }
357 
IsGroupBaseField() const358 bool XclPCField::IsGroupBaseField() const
359 {
360     return ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_HASCHILD );
361 }
362 
IsGroupChildField() const363 bool XclPCField::IsGroupChildField() const
364 {
365     return (meFieldType == EXC_PCFIELD_STDGROUP) || (meFieldType == EXC_PCFIELD_DATECHILD);
366 }
367 
GetBaseFieldIndex() const368 sal_uInt16 XclPCField::GetBaseFieldIndex() const
369 {
370     return IsGroupChildField() ? maFieldInfo.mnGroupBase : mnFieldIdx;
371 }
372 
HasOrigItems() const373 bool XclPCField::HasOrigItems() const
374 {
375     return IsSupportedField() && ((maFieldInfo.mnOrigItems > 0) || HasPostponedItems());
376 }
377 
HasInlineItems() const378 bool XclPCField::HasInlineItems() const
379 {
380     return (IsStandardField() || IsGroupField()) && ((maFieldInfo.mnGroupItems > 0) || (maFieldInfo.mnOrigItems > 0));
381 }
382 
HasPostponedItems() const383 bool XclPCField::HasPostponedItems() const
384 {
385     return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_POSTPONE );
386 }
387 
Has16BitIndexes() const388 bool XclPCField::Has16BitIndexes() const
389 {
390     return IsStandardField() && ::get_flag( maFieldInfo.mnFlags, EXC_SXFIELD_16BIT );
391 }
392 
393 // Pivot cache settings =======================================================
394 
395 /** Contains data for a pivot cache (SXDB record). */
XclPCInfo()396 XclPCInfo::XclPCInfo() :
397     mnSrcRecs( 0 ),
398     mnStrmId( 0xFFFF ),
399     mnFlags( EXC_SXDB_DEFAULTFLAGS ),
400     mnBlockRecs( EXC_SXDB_BLOCKRECS ),
401     mnStdFields( 0 ),
402     mnTotalFields( 0 ),
403     mnSrcType( EXC_SXDB_SRC_SHEET )
404 {
405 }
406 
operator >>(XclImpStream & rStrm,XclPCInfo & rInfo)407 XclImpStream& operator>>( XclImpStream& rStrm, XclPCInfo& rInfo )
408 {
409     rStrm   >> rInfo.mnSrcRecs
410             >> rInfo.mnStrmId
411             >> rInfo.mnFlags
412             >> rInfo.mnBlockRecs
413             >> rInfo.mnStdFields
414             >> rInfo.mnTotalFields;
415     rStrm.Ignore( 2 );
416     rStrm   >> rInfo.mnSrcType;
417     rInfo.maUserName = rStrm.ReadUniString();
418     return rStrm;
419 }
420 
operator <<(XclExpStream & rStrm,const XclPCInfo & rInfo)421 XclExpStream& operator<<( XclExpStream& rStrm, const XclPCInfo& rInfo )
422 {
423     return rStrm
424         << rInfo.mnSrcRecs
425         << rInfo.mnStrmId
426         << rInfo.mnFlags
427         << rInfo.mnBlockRecs
428         << rInfo.mnStdFields
429         << rInfo.mnTotalFields
430         << sal_uInt16( 0 )
431         << rInfo.mnSrcType
432         << XclExpString( rInfo.maUserName );
433 }
434 
435 // ============================================================================
436 // Pivot table
437 // ============================================================================
438 
439 // cached name ================================================================
440 
operator >>(XclImpStream & rStrm,XclPTCachedName & rCachedName)441 XclImpStream& operator>>( XclImpStream& rStrm, XclPTCachedName& rCachedName )
442 {
443     sal_uInt16 nStrLen;
444     rStrm >> nStrLen;
445     rCachedName.mbUseCache = nStrLen == EXC_PT_NOSTRING;
446     if( rCachedName.mbUseCache )
447         rCachedName.maName.Erase();
448     else
449         rCachedName.maName = rStrm.ReadUniString( nStrLen );
450     return rStrm;
451 }
452 
operator <<(XclExpStream & rStrm,const XclPTCachedName & rCachedName)453 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTCachedName& rCachedName )
454 {
455     if( rCachedName.mbUseCache )
456         rStrm << EXC_PT_NOSTRING;
457     else
458         rStrm << XclExpString( rCachedName.maName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN );
459     return rStrm;
460 }
461 
462 // ----------------------------------------------------------------------------
463 
GetVisName() const464 const String* XclPTVisNameInfo::GetVisName() const
465 {
466     return HasVisName() ? &maVisName.maName : 0;
467 }
468 
SetVisName(const String & rName)469 void XclPTVisNameInfo::SetVisName( const String& rName )
470 {
471     maVisName.maName = rName;
472     maVisName.mbUseCache = rName.Len() == 0;
473 }
474 
475 // Field item settings ========================================================
476 
XclPTItemInfo()477 XclPTItemInfo::XclPTItemInfo() :
478     mnType( EXC_SXVI_TYPE_DATA ),
479     mnFlags( EXC_SXVI_DEFAULTFLAGS ),
480     mnCacheIdx( EXC_SXVI_DEFAULT_CACHE )
481 {
482 }
483 
operator >>(XclImpStream & rStrm,XclPTItemInfo & rInfo)484 XclImpStream& operator>>( XclImpStream& rStrm, XclPTItemInfo& rInfo )
485 {
486     return rStrm
487         >> rInfo.mnType
488         >> rInfo.mnFlags
489         >> rInfo.mnCacheIdx
490         >> rInfo.maVisName;
491 }
492 
operator <<(XclExpStream & rStrm,const XclPTItemInfo & rInfo)493 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTItemInfo& rInfo )
494 {
495     return rStrm
496         << rInfo.mnType
497         << rInfo.mnFlags
498         << rInfo.mnCacheIdx
499         << rInfo.maVisName;
500 }
501 
502 // General field settings =====================================================
503 
XclPTFieldInfo()504 XclPTFieldInfo::XclPTFieldInfo() :
505     mnAxes( EXC_SXVD_AXIS_NONE ),
506     mnSubtCount( 1 ),
507     mnSubtotals( EXC_SXVD_SUBT_DEFAULT ),
508     mnItemCount( 0 ),
509     mnCacheIdx( EXC_SXVD_DEFAULT_CACHE )
510 {
511 }
512 
GetApiOrient(sal_uInt16 nMask) const513 DataPilotFieldOrientation XclPTFieldInfo::GetApiOrient( sal_uInt16 nMask ) const
514 {
515     using namespace ::com::sun::star::sheet;
516     DataPilotFieldOrientation eOrient = DataPilotFieldOrientation_HIDDEN;
517     sal_uInt16 nUsedAxes = mnAxes & nMask;
518     if( nUsedAxes & EXC_SXVD_AXIS_ROW )
519         eOrient = DataPilotFieldOrientation_ROW;
520     else if( nUsedAxes & EXC_SXVD_AXIS_COL )
521         eOrient = DataPilotFieldOrientation_COLUMN;
522     else if( nUsedAxes & EXC_SXVD_AXIS_PAGE )
523         eOrient = DataPilotFieldOrientation_PAGE;
524     else if( nUsedAxes & EXC_SXVD_AXIS_DATA )
525         eOrient = DataPilotFieldOrientation_DATA;
526     return eOrient;
527 }
528 
AddApiOrient(DataPilotFieldOrientation eOrient)529 void XclPTFieldInfo::AddApiOrient( DataPilotFieldOrientation eOrient )
530 {
531     using namespace ::com::sun::star::sheet;
532     switch( eOrient )
533     {
534         case DataPilotFieldOrientation_ROW:     mnAxes |= EXC_SXVD_AXIS_ROW;    break;
535         case DataPilotFieldOrientation_COLUMN:  mnAxes |= EXC_SXVD_AXIS_COL;    break;
536         case DataPilotFieldOrientation_PAGE:    mnAxes |= EXC_SXVD_AXIS_PAGE;   break;
537         case DataPilotFieldOrientation_DATA:    mnAxes |= EXC_SXVD_AXIS_DATA;   break;
538         default:;
539     }
540 }
541 
542 //! TODO: should be a Sequence<GeneralFunction> in ScDPSaveData
GetSubtotals(XclPTSubtotalVec & rSubtotals) const543 void XclPTFieldInfo::GetSubtotals( XclPTSubtotalVec& rSubtotals ) const
544 {
545     rSubtotals.clear();
546     rSubtotals.reserve( 16 );
547 
548     using namespace ::com::sun::star::sheet;
549     if( mnSubtotals & EXC_SXVD_SUBT_DEFAULT )   rSubtotals.push_back( GeneralFunction_AUTO );
550     if( mnSubtotals & EXC_SXVD_SUBT_SUM )       rSubtotals.push_back( GeneralFunction_SUM );
551     if( mnSubtotals & EXC_SXVD_SUBT_COUNT )     rSubtotals.push_back( GeneralFunction_COUNT );
552     if( mnSubtotals & EXC_SXVD_SUBT_AVERAGE )   rSubtotals.push_back( GeneralFunction_AVERAGE );
553     if( mnSubtotals & EXC_SXVD_SUBT_MAX )       rSubtotals.push_back( GeneralFunction_MAX );
554     if( mnSubtotals & EXC_SXVD_SUBT_MIN )       rSubtotals.push_back( GeneralFunction_MIN );
555     if( mnSubtotals & EXC_SXVD_SUBT_PROD )      rSubtotals.push_back( GeneralFunction_PRODUCT );
556     if( mnSubtotals & EXC_SXVD_SUBT_COUNTNUM )  rSubtotals.push_back( GeneralFunction_COUNTNUMS );
557     if( mnSubtotals & EXC_SXVD_SUBT_STDDEV )    rSubtotals.push_back( GeneralFunction_STDEV );
558     if( mnSubtotals & EXC_SXVD_SUBT_STDDEVP )   rSubtotals.push_back( GeneralFunction_STDEVP );
559     if( mnSubtotals & EXC_SXVD_SUBT_VAR )       rSubtotals.push_back( GeneralFunction_VAR );
560     if( mnSubtotals & EXC_SXVD_SUBT_VARP )      rSubtotals.push_back( GeneralFunction_VARP );
561 }
562 
SetSubtotals(const XclPTSubtotalVec & rSubtotals)563 void XclPTFieldInfo::SetSubtotals( const XclPTSubtotalVec& rSubtotals )
564 {
565     mnSubtotals = EXC_SXVD_SUBT_NONE;
566     using namespace ::com::sun::star::sheet;
567     for( XclPTSubtotalVec::const_iterator aIt = rSubtotals.begin(), aEnd = rSubtotals.end(); aIt != aEnd; ++aIt )
568     {
569         switch( *aIt )
570         {
571             case GeneralFunction_AUTO:      mnSubtotals |= EXC_SXVD_SUBT_DEFAULT;   break;
572             case GeneralFunction_SUM:       mnSubtotals |= EXC_SXVD_SUBT_SUM;       break;
573             case GeneralFunction_COUNT:     mnSubtotals |= EXC_SXVD_SUBT_COUNT;     break;
574             case GeneralFunction_AVERAGE:   mnSubtotals |= EXC_SXVD_SUBT_AVERAGE;   break;
575             case GeneralFunction_MAX:       mnSubtotals |= EXC_SXVD_SUBT_MAX;       break;
576             case GeneralFunction_MIN:       mnSubtotals |= EXC_SXVD_SUBT_MIN;       break;
577             case GeneralFunction_PRODUCT:   mnSubtotals |= EXC_SXVD_SUBT_PROD;      break;
578             case GeneralFunction_COUNTNUMS: mnSubtotals |= EXC_SXVD_SUBT_COUNTNUM;  break;
579             case GeneralFunction_STDEV:     mnSubtotals |= EXC_SXVD_SUBT_STDDEV;    break;
580             case GeneralFunction_STDEVP:    mnSubtotals |= EXC_SXVD_SUBT_STDDEVP;   break;
581             case GeneralFunction_VAR:       mnSubtotals |= EXC_SXVD_SUBT_VAR;       break;
582             case GeneralFunction_VARP:      mnSubtotals |= EXC_SXVD_SUBT_VARP;      break;
583         }
584     }
585 
586     mnSubtCount = 0;
587     for( sal_uInt16 nMask = 0x8000; nMask; nMask >>= 1 )
588         if( mnSubtotals & nMask )
589             ++mnSubtCount;
590 }
591 
operator >>(XclImpStream & rStrm,XclPTFieldInfo & rInfo)592 XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldInfo& rInfo )
593 {
594     // rInfo.mnCacheIdx is not part of the SXVD record
595     return rStrm
596         >> rInfo.mnAxes
597         >> rInfo.mnSubtCount
598         >> rInfo.mnSubtotals
599         >> rInfo.mnItemCount
600         >> rInfo.maVisName;
601 }
602 
operator <<(XclExpStream & rStrm,const XclPTFieldInfo & rInfo)603 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo )
604 {
605     // rInfo.mnCacheIdx is not part of the SXVD record
606     return rStrm
607         << rInfo.mnAxes
608         << rInfo.mnSubtCount
609         << rInfo.mnSubtotals
610         << rInfo.mnItemCount
611         << rInfo.maVisName;
612 }
613 
614 // Extended field settings ====================================================
615 
XclPTFieldExtInfo()616 XclPTFieldExtInfo::XclPTFieldExtInfo() :
617     mnFlags( EXC_SXVDEX_DEFAULTFLAGS ),
618     mnSortField( EXC_SXVDEX_SORT_OWN ),
619     mnShowField( EXC_SXVDEX_SHOW_NONE ),
620     mnNumFmt(0),
621     mpFieldTotalName(NULL)
622 {
623 }
624 
GetApiSortMode() const625 sal_Int32 XclPTFieldExtInfo::GetApiSortMode() const
626 {
627     sal_Int32 nSortMode = ScDPSortMode::MANUAL;
628     if( ::get_flag( mnFlags, EXC_SXVDEX_SORT ) )
629         nSortMode = (mnSortField == EXC_SXVDEX_SORT_OWN) ? ScDPSortMode::NAME : ScDPSortMode::DATA;
630     return nSortMode;
631 }
632 
SetApiSortMode(sal_Int32 nSortMode)633 void XclPTFieldExtInfo::SetApiSortMode( sal_Int32 nSortMode )
634 {
635     bool bSort = (nSortMode == ScDPSortMode::NAME) || (nSortMode == ScDPSortMode::DATA);
636     ::set_flag( mnFlags, EXC_SXVDEX_SORT, bSort );
637     if( nSortMode == ScDPSortMode::NAME )
638         mnSortField = EXC_SXVDEX_SORT_OWN;  // otherwise sort field has to be set by caller
639 }
640 
GetApiAutoShowMode() const641 sal_Int32 XclPTFieldExtInfo::GetApiAutoShowMode() const
642 {
643     return ::get_flagvalue( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC,
644         ScDPShowItemsMode::FROM_TOP, ScDPShowItemsMode::FROM_BOTTOM );
645 }
646 
SetApiAutoShowMode(sal_Int32 nShowMode)647 void XclPTFieldExtInfo::SetApiAutoShowMode( sal_Int32 nShowMode )
648 {
649     ::set_flag( mnFlags, EXC_SXVDEX_AUTOSHOW_ASC, nShowMode == ScDPShowItemsMode::FROM_TOP );
650 }
651 
GetApiAutoShowCount() const652 sal_Int32 XclPTFieldExtInfo::GetApiAutoShowCount() const
653 {
654     return ::extract_value< sal_Int32 >( mnFlags, 24, 8 );
655 }
656 
SetApiAutoShowCount(sal_Int32 nShowCount)657 void XclPTFieldExtInfo::SetApiAutoShowCount( sal_Int32 nShowCount )
658 {
659     ::insert_value( mnFlags, limit_cast< sal_uInt8 >( nShowCount ), 24, 8 );
660 }
661 
GetApiLayoutMode() const662 sal_Int32 XclPTFieldExtInfo::GetApiLayoutMode() const
663 {
664     sal_Int32 nLayoutMode = ScDPLayoutMode::TABULAR_LAYOUT;
665     if( ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT ) )
666         nLayoutMode = ::get_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP ) ?
667             ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP : ScDPLayoutMode::OUTLINE_SUBTOTALS_BOTTOM;
668     return nLayoutMode;
669 }
670 
SetApiLayoutMode(sal_Int32 nLayoutMode)671 void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode )
672 {
673     ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_REPORT, nLayoutMode != ScDPLayoutMode::TABULAR_LAYOUT );
674     ::set_flag( mnFlags, EXC_SXVDEX_LAYOUT_TOP, nLayoutMode == ScDPLayoutMode::OUTLINE_SUBTOTALS_TOP );
675 }
676 
operator >>(XclImpStream & rStrm,XclPTFieldExtInfo & rInfo)677 XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo )
678 {
679     sal_uInt8 nNameLen = 0;
680     rStrm >> rInfo.mnFlags
681           >> rInfo.mnSortField
682           >> rInfo.mnShowField
683           >> rInfo.mnNumFmt
684           >> nNameLen;
685 
686     rStrm.Ignore(10);
687     if (nNameLen != 0xFF)
688         // Custom field total name is used.  Pick it up.
689         rInfo.mpFieldTotalName.reset(new rtl::OUString(rStrm.ReadUniString(nNameLen, 0)));
690 
691     return rStrm;
692 }
693 
operator <<(XclExpStream & rStrm,const XclPTFieldExtInfo & rInfo)694 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
695 {
696     rStrm   << rInfo.mnFlags
697             << rInfo.mnSortField
698             << rInfo.mnShowField
699             << EXC_SXVDEX_FORMAT_NONE;
700 
701     if (rInfo.mpFieldTotalName.get() && rInfo.mpFieldTotalName->getLength() > 0)
702     {
703         rtl::OUString aFinalName = *rInfo.mpFieldTotalName;
704         if (aFinalName.getLength() >= 254)
705             aFinalName = aFinalName.copy(0, 254);
706         sal_uInt8 nNameLen = static_cast<sal_uInt8>(aFinalName.getLength());
707         rStrm << nNameLen;
708         rStrm.WriteZeroBytes(10);
709         rStrm << XclExpString(aFinalName, EXC_STR_NOHEADER);
710     }
711     else
712     {
713         rStrm << sal_uInt16(0xFFFF);
714         rStrm.WriteZeroBytes(8);
715     }
716     return rStrm;
717 }
718 
719 // Page field settings ========================================================
720 
XclPTPageFieldInfo()721 XclPTPageFieldInfo::XclPTPageFieldInfo() :
722     mnField( 0 ),
723     mnSelItem( EXC_SXPI_ALLITEMS ),
724     mnObjId( 0xFFFF )
725 {
726 }
727 
operator >>(XclImpStream & rStrm,XclPTPageFieldInfo & rInfo)728 XclImpStream& operator>>( XclImpStream& rStrm, XclPTPageFieldInfo& rInfo )
729 {
730     return rStrm
731         >> rInfo.mnField
732         >> rInfo.mnSelItem
733         >> rInfo.mnObjId;
734 }
735 
operator <<(XclExpStream & rStrm,const XclPTPageFieldInfo & rInfo)736 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTPageFieldInfo& rInfo )
737 {
738     return rStrm
739         << rInfo.mnField
740         << rInfo.mnSelItem
741         << rInfo.mnObjId;
742 }
743 
744 // Data field settings ========================================================
745 
XclPTDataFieldInfo()746 XclPTDataFieldInfo::XclPTDataFieldInfo() :
747     mnField( 0 ),
748     mnAggFunc( EXC_SXDI_FUNC_SUM ),
749     mnRefType( EXC_SXDI_REF_NORMAL ),
750     mnRefField( 0 ),
751     mnRefItem( 0 ),
752     mnNumFmt( 0 )
753 {
754 }
755 
GetApiAggFunc() const756 GeneralFunction XclPTDataFieldInfo::GetApiAggFunc() const
757 {
758     using namespace ::com::sun::star::sheet;
759     GeneralFunction eAggFunc;
760     switch( mnAggFunc )
761     {
762         case EXC_SXDI_FUNC_SUM:         eAggFunc = GeneralFunction_SUM;         break;
763         case EXC_SXDI_FUNC_COUNT:       eAggFunc = GeneralFunction_COUNT;       break;
764         case EXC_SXDI_FUNC_AVERAGE:     eAggFunc = GeneralFunction_AVERAGE;     break;
765         case EXC_SXDI_FUNC_MAX:         eAggFunc = GeneralFunction_MAX;         break;
766         case EXC_SXDI_FUNC_MIN:         eAggFunc = GeneralFunction_MIN;         break;
767         case EXC_SXDI_FUNC_PRODUCT:     eAggFunc = GeneralFunction_PRODUCT;     break;
768         case EXC_SXDI_FUNC_COUNTNUM:    eAggFunc = GeneralFunction_COUNTNUMS;   break;
769         case EXC_SXDI_FUNC_STDDEV:      eAggFunc = GeneralFunction_STDEV;       break;
770         case EXC_SXDI_FUNC_STDDEVP:     eAggFunc = GeneralFunction_STDEVP;      break;
771         case EXC_SXDI_FUNC_VAR:         eAggFunc = GeneralFunction_VAR;         break;
772         case EXC_SXDI_FUNC_VARP:        eAggFunc = GeneralFunction_VARP;        break;
773         default:                        eAggFunc = GeneralFunction_SUM;
774     }
775     return eAggFunc;
776 }
777 
SetApiAggFunc(GeneralFunction eAggFunc)778 void XclPTDataFieldInfo::SetApiAggFunc( GeneralFunction eAggFunc )
779 {
780     using namespace ::com::sun::star::sheet;
781     switch( eAggFunc )
782     {
783         case GeneralFunction_SUM:       mnAggFunc = EXC_SXDI_FUNC_SUM;      break;
784         case GeneralFunction_COUNT:     mnAggFunc = EXC_SXDI_FUNC_COUNT;    break;
785         case GeneralFunction_AVERAGE:   mnAggFunc = EXC_SXDI_FUNC_AVERAGE;  break;
786         case GeneralFunction_MAX:       mnAggFunc = EXC_SXDI_FUNC_MAX;      break;
787         case GeneralFunction_MIN:       mnAggFunc = EXC_SXDI_FUNC_MIN;      break;
788         case GeneralFunction_PRODUCT:   mnAggFunc = EXC_SXDI_FUNC_PRODUCT;  break;
789         case GeneralFunction_COUNTNUMS: mnAggFunc = EXC_SXDI_FUNC_COUNTNUM; break;
790         case GeneralFunction_STDEV:     mnAggFunc = EXC_SXDI_FUNC_STDDEV;   break;
791         case GeneralFunction_STDEVP:    mnAggFunc = EXC_SXDI_FUNC_STDDEVP;  break;
792         case GeneralFunction_VAR:       mnAggFunc = EXC_SXDI_FUNC_VAR;      break;
793         case GeneralFunction_VARP:      mnAggFunc = EXC_SXDI_FUNC_VARP;     break;
794         default:                        mnAggFunc = EXC_SXDI_FUNC_SUM;
795     }
796 }
797 
GetApiRefType() const798 sal_Int32 XclPTDataFieldInfo::GetApiRefType() const
799 {
800     namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
801     sal_Int32 nRefType;
802     switch( mnRefType )
803     {
804         case EXC_SXDI_REF_DIFF:         nRefType = ScDPRefType::ITEM_DIFFERENCE;            break;
805         case EXC_SXDI_REF_PERC:         nRefType = ScDPRefType::ITEM_PERCENTAGE;            break;
806         case EXC_SXDI_REF_PERC_DIFF:    nRefType = ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE; break;
807         case EXC_SXDI_REF_RUN_TOTAL:    nRefType = ScDPRefType::RUNNING_TOTAL;              break;
808         case EXC_SXDI_REF_PERC_ROW:     nRefType = ScDPRefType::ROW_PERCENTAGE;             break;
809         case EXC_SXDI_REF_PERC_COL:     nRefType = ScDPRefType::COLUMN_PERCENTAGE;          break;
810         case EXC_SXDI_REF_PERC_TOTAL:   nRefType = ScDPRefType::TOTAL_PERCENTAGE;           break;
811         case EXC_SXDI_REF_INDEX:        nRefType = ScDPRefType::INDEX;                      break;
812         default:                        nRefType = ScDPRefType::NONE;
813     }
814     return nRefType;
815 }
816 
SetApiRefType(sal_Int32 nRefType)817 void XclPTDataFieldInfo::SetApiRefType( sal_Int32 nRefType )
818 {
819     namespace ScDPRefType = ::com::sun::star::sheet::DataPilotFieldReferenceType;
820     switch( nRefType )
821     {
822         case ScDPRefType::ITEM_DIFFERENCE:              mnRefType = EXC_SXDI_REF_DIFF;      break;
823         case ScDPRefType::ITEM_PERCENTAGE:              mnRefType = EXC_SXDI_REF_PERC;      break;
824         case ScDPRefType::ITEM_PERCENTAGE_DIFFERENCE:   mnRefType = EXC_SXDI_REF_PERC_DIFF; break;
825         case ScDPRefType::RUNNING_TOTAL:                mnRefType = EXC_SXDI_REF_RUN_TOTAL; break;
826         case ScDPRefType::ROW_PERCENTAGE:               mnRefType = EXC_SXDI_REF_PERC_ROW;  break;
827         case ScDPRefType::COLUMN_PERCENTAGE:            mnRefType = EXC_SXDI_REF_PERC_COL;  break;
828         case ScDPRefType::TOTAL_PERCENTAGE:             mnRefType = EXC_SXDI_REF_PERC_TOTAL;break;
829         case ScDPRefType::INDEX:                        mnRefType = EXC_SXDI_REF_INDEX;     break;
830         default:                                        mnRefType = EXC_SXDI_REF_NORMAL;
831     }
832 }
833 
GetApiRefItemType() const834 sal_Int32 XclPTDataFieldInfo::GetApiRefItemType() const
835 {
836     sal_Int32 nRefItemType;
837     switch( mnRefItem )
838     {
839         case EXC_SXDI_PREVITEM: nRefItemType = ScDPRefItemType::PREVIOUS;   break;
840         case EXC_SXDI_NEXTITEM: nRefItemType = ScDPRefItemType::NEXT;       break;
841         default:                nRefItemType = ScDPRefItemType::NAMED;
842     }
843     return nRefItemType;
844 }
845 
SetApiRefItemType(sal_Int32 nRefItemType)846 void XclPTDataFieldInfo::SetApiRefItemType( sal_Int32 nRefItemType )
847 {
848     switch( nRefItemType )
849     {
850         case ScDPRefItemType::PREVIOUS: mnRefItem = EXC_SXDI_PREVITEM;  break;
851         case ScDPRefItemType::NEXT:     mnRefItem = EXC_SXDI_NEXTITEM;  break;
852         // nothing for named item reference
853     }
854 }
855 
operator >>(XclImpStream & rStrm,XclPTDataFieldInfo & rInfo)856 XclImpStream& operator>>( XclImpStream& rStrm, XclPTDataFieldInfo& rInfo )
857 {
858     return rStrm
859         >> rInfo.mnField
860         >> rInfo.mnAggFunc
861         >> rInfo.mnRefType
862         >> rInfo.mnRefField
863         >> rInfo.mnRefItem
864         >> rInfo.mnNumFmt
865         >> rInfo.maVisName;
866 }
867 
operator <<(XclExpStream & rStrm,const XclPTDataFieldInfo & rInfo)868 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTDataFieldInfo& rInfo )
869 {
870     return rStrm
871         << rInfo.mnField
872         << rInfo.mnAggFunc
873         << rInfo.mnRefType
874         << rInfo.mnRefField
875         << rInfo.mnRefItem
876         << rInfo.mnNumFmt
877         << rInfo.maVisName;
878 }
879 
880 // Pivot table settings =======================================================
881 
XclPTInfo()882 XclPTInfo::XclPTInfo() :
883     mnFirstHeadRow( 0 ),
884     mnCacheIdx( 0xFFFF ),
885     mnDataAxis( EXC_SXVD_AXIS_NONE ),
886     mnDataPos( EXC_SXVIEW_DATALAST ),
887     mnFields( 0 ),
888     mnRowFields( 0 ),
889     mnColFields( 0 ),
890     mnPageFields( 0 ),
891     mnDataFields( 0 ),
892     mnDataRows( 0 ),
893     mnDataCols( 0 ),
894     mnFlags( EXC_SXVIEW_DEFAULTFLAGS ),
895     mnAutoFmtIdx( EXC_SXVIEW_AUTOFMT )
896 {
897 }
898 
operator >>(XclImpStream & rStrm,XclPTInfo & rInfo)899 XclImpStream& operator>>( XclImpStream& rStrm, XclPTInfo& rInfo )
900 {
901     sal_uInt16 nTabLen, nDataLen;
902 
903     rStrm   >> rInfo.maOutXclRange
904             >> rInfo.mnFirstHeadRow
905             >> rInfo.maDataXclPos
906             >> rInfo.mnCacheIdx;
907     rStrm.Ignore( 2 );
908     rStrm   >> rInfo.mnDataAxis >> rInfo.mnDataPos
909             >> rInfo.mnFields
910             >> rInfo.mnRowFields >> rInfo.mnColFields
911             >> rInfo.mnPageFields >> rInfo.mnDataFields
912             >> rInfo.mnDataRows >> rInfo.mnDataCols
913             >> rInfo.mnFlags
914             >> rInfo.mnAutoFmtIdx
915             >> nTabLen >> nDataLen;
916     rInfo.maTableName = rStrm.ReadUniString( nTabLen );
917     rInfo.maDataName = rStrm.ReadUniString( nDataLen );
918     return rStrm;
919 }
920 
operator <<(XclExpStream & rStrm,const XclPTInfo & rInfo)921 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTInfo& rInfo )
922 {
923     XclExpString aXclTableName( rInfo.maTableName );
924     XclExpString aXclDataName( rInfo.maDataName );
925 
926     rStrm   << rInfo.maOutXclRange
927             << rInfo.mnFirstHeadRow
928             << rInfo.maDataXclPos
929             << rInfo.mnCacheIdx
930             << sal_uInt16( 0 )
931             << rInfo.mnDataAxis << rInfo.mnDataPos
932             << rInfo.mnFields
933             << rInfo.mnRowFields << rInfo.mnColFields
934             << rInfo.mnPageFields << rInfo.mnDataFields
935             << rInfo.mnDataRows << rInfo.mnDataCols
936             << rInfo.mnFlags
937             << rInfo.mnAutoFmtIdx
938             << aXclTableName.Len() << aXclDataName.Len();
939     aXclTableName.WriteFlagField( rStrm );
940     aXclTableName.WriteBuffer( rStrm );
941     aXclDataName.WriteFlagField( rStrm );
942     aXclDataName.WriteBuffer( rStrm );
943     return rStrm;
944 }
945 
946 // Extended pivot table settings ==============================================
947 
XclPTExtInfo()948 XclPTExtInfo::XclPTExtInfo() :
949     mnSxformulaRecs( 0 ),
950     mnSxselectRecs( 0 ),
951     mnPagePerRow( 0 ),
952     mnPagePerCol( 0 ),
953     mnFlags( EXC_SXEX_DEFAULTFLAGS )
954 {
955 }
956 
operator >>(XclImpStream & rStrm,XclPTExtInfo & rInfo)957 XclImpStream& operator>>( XclImpStream& rStrm, XclPTExtInfo& rInfo )
958 {
959     rStrm >> rInfo.mnSxformulaRecs;
960     rStrm.Ignore( 6 );
961     return rStrm
962         >> rInfo.mnSxselectRecs
963         >> rInfo.mnPagePerRow
964         >> rInfo.mnPagePerCol
965         >> rInfo.mnFlags;
966 }
967 
operator <<(XclExpStream & rStrm,const XclPTExtInfo & rInfo)968 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo )
969 {
970     return rStrm
971         << rInfo.mnSxformulaRecs
972         << EXC_PT_NOSTRING              // length of alt. error text
973         << EXC_PT_NOSTRING              // length of alt. empty text
974         << EXC_PT_NOSTRING              // length of tag
975         << rInfo.mnSxselectRecs
976         << rInfo.mnPagePerRow
977         << rInfo.mnPagePerCol
978         << rInfo.mnFlags
979         << EXC_PT_NOSTRING              // length of page field style name
980         << EXC_PT_NOSTRING              // length of table style name
981         << EXC_PT_NOSTRING;             // length of vacate style name
982 }
983 
984 // ============================================================================
985 
986 // Pivot table autoformat settings ============================================
987 
988 /**
989 classic     : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
990 default     : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
991 report01    : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00
992 report02    : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00
993 report03    : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00
994 report04    : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00
995 report05    : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00
996 report06    : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00
997 report07    : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00
998 report08    : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00
999 report09    : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00
1000 report10    : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00
1001 table01     : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00
1002 table02     : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00
1003 table03     : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00
1004 table04     : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00
1005 table05     : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00
1006 table06     : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00
1007 table07     : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00
1008 table08     : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00
1009 table09     : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00
1010 table10     : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00
1011 none        : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00
1012 **/
1013 
XclPTViewEx9Info()1014 XclPTViewEx9Info::XclPTViewEx9Info() :
1015     mbReport( 0 ),
1016     mnAutoFormat( 0 ),
1017     mnGridLayout( 0x10 )
1018 {
1019 }
1020 
Init(const ScDPObject & rDPObj)1021 void XclPTViewEx9Info::Init( const ScDPObject& rDPObj )
1022 {
1023     if( rDPObj.GetHeaderLayout() )
1024     {
1025         mbReport     = 0;
1026         mnAutoFormat = 1;
1027         mnGridLayout = 0;
1028     }
1029     else
1030     {
1031         // Report1 for now
1032         // TODO : sync with autoformat indicies
1033         mbReport     = 2;
1034         mnAutoFormat = 1;
1035         mnGridLayout = 0x10;
1036     }
1037 
1038     const ScDPSaveData* pData = rDPObj.GetSaveData();
1039     if (pData)
1040     {
1041         const rtl::OUString* pGrandTotal = pData->GetGrandTotalName();
1042         if (pGrandTotal)
1043             maGrandTotalName = *pGrandTotal;
1044     }
1045 }
1046 
operator >>(XclImpStream & rStrm,XclPTViewEx9Info & rInfo)1047 XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo )
1048 {
1049     rStrm.Ignore( 2 );
1050     rStrm >> rInfo.mbReport;            /// 2 for report* fmts ?
1051     rStrm.Ignore( 6 );
1052     rStrm >> rInfo.mnAutoFormat >> rInfo.mnGridLayout;
1053     rInfo.maGrandTotalName = rStrm.ReadUniString();
1054     return rStrm;
1055 }
1056 
operator <<(XclExpStream & rStrm,const XclPTViewEx9Info & rInfo)1057 XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo )
1058 {
1059     return rStrm
1060         << EXC_PT_AUTOFMT_HEADER
1061         << rInfo.mbReport
1062         << EXC_PT_AUTOFMT_ZERO
1063         << EXC_PT_AUTOFMT_FLAGS
1064         << rInfo.mnAutoFormat
1065         << rInfo.mnGridLayout
1066         << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN);
1067 }
1068 
1069