1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <pivotcachefragment.hxx>
22 #include <osl/diagnose.h>
23 #include <oox/token/namespaces.hxx>
24 #include <biffhelper.hxx>
25 #include <formulabuffer.hxx>
26 #include <pivotcachebuffer.hxx>
27 #include <worksheetbuffer.hxx>
31 using namespace ::oox::core
;
33 PivotCacheFieldContext::PivotCacheFieldContext( WorkbookFragmentBase
& rFragment
, PivotCacheField
& rCacheField
) :
34 WorkbookContextBase( rFragment
),
35 mrCacheField( rCacheField
)
39 ContextHandlerRef
PivotCacheFieldContext::onCreateContext( sal_Int32 nElement
, const AttributeList
& rAttribs
)
41 switch( getCurrentElement() )
43 case XLS_TOKEN( cacheField
):
44 if( nElement
== XLS_TOKEN( sharedItems
) ) { mrCacheField
.importSharedItems( rAttribs
); return this; }
45 if( nElement
== XLS_TOKEN( fieldGroup
) ) { mrCacheField
.importFieldGroup( rAttribs
); return this; }
48 case XLS_TOKEN( fieldGroup
):
51 case XLS_TOKEN( rangePr
): mrCacheField
.importRangePr( rAttribs
); break;
52 case XLS_TOKEN( discretePr
): return this;
53 case XLS_TOKEN( groupItems
): return this;
57 case XLS_TOKEN( sharedItems
): mrCacheField
.importSharedItem( nElement
, rAttribs
); break;
58 case XLS_TOKEN( discretePr
): mrCacheField
.importDiscretePrItem( nElement
, rAttribs
); break;
59 case XLS_TOKEN( groupItems
): mrCacheField
.importGroupItem( nElement
, rAttribs
); break;
64 void PivotCacheFieldContext::onStartElement( const AttributeList
& rAttribs
)
67 mrCacheField
.importCacheField( rAttribs
);
70 ContextHandlerRef
PivotCacheFieldContext::onCreateRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
)
72 switch( getCurrentElement() )
74 case BIFF12_ID_PCDFIELD
:
77 case BIFF12_ID_PCDFSHAREDITEMS
: mrCacheField
.importPCDFSharedItems( rStrm
); return this;
78 case BIFF12_ID_PCDFIELDGROUP
: mrCacheField
.importPCDFieldGroup( rStrm
); return this;
82 case BIFF12_ID_PCDFIELDGROUP
:
85 case BIFF12_ID_PCDFRANGEPR
: mrCacheField
.importPCDFRangePr( rStrm
); break;
86 case BIFF12_ID_PCDFDISCRETEPR
: return this;
87 case BIFF12_ID_PCDFGROUPITEMS
: return this;
91 case BIFF12_ID_PCDFSHAREDITEMS
: mrCacheField
.importPCDFSharedItem( nRecId
, rStrm
); break;
92 case BIFF12_ID_PCDFDISCRETEPR
: mrCacheField
.importPCDFDiscretePrItem( nRecId
, rStrm
); break;
93 case BIFF12_ID_PCDFGROUPITEMS
: mrCacheField
.importPCDFGroupItem( nRecId
, rStrm
); break;
98 void PivotCacheFieldContext::onStartRecord( SequenceInputStream
& rStrm
)
100 if( isRootElement() )
101 mrCacheField
.importPCDField( rStrm
);
104 PivotCacheDefinitionFragment::PivotCacheDefinitionFragment(
105 const WorkbookHelper
& rHelper
, const OUString
& rFragmentPath
, PivotCache
& rPivotCache
) :
106 WorkbookFragmentBase( rHelper
, rFragmentPath
),
107 mrPivotCache( rPivotCache
)
111 ContextHandlerRef
PivotCacheDefinitionFragment::onCreateContext( sal_Int32 nElement
, const AttributeList
& rAttribs
)
113 switch( getCurrentElement() )
115 case XML_ROOT_CONTEXT
:
116 if( nElement
== XLS_TOKEN( pivotCacheDefinition
) ) { mrPivotCache
.importPivotCacheDefinition( rAttribs
); return this; }
119 case XLS_TOKEN( pivotCacheDefinition
):
122 case XLS_TOKEN( cacheSource
): mrPivotCache
.importCacheSource( rAttribs
); return this;
123 case XLS_TOKEN( cacheFields
): return this;
127 case XLS_TOKEN( cacheSource
):
128 if( nElement
== XLS_TOKEN( worksheetSource
) ) mrPivotCache
.importWorksheetSource( rAttribs
, getRelations() );
131 case XLS_TOKEN( cacheFields
):
132 if( nElement
== XLS_TOKEN( cacheField
) ) return new PivotCacheFieldContext( *this, mrPivotCache
.createCacheField() );
138 ContextHandlerRef
PivotCacheDefinitionFragment::onCreateRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
)
140 switch( getCurrentElement() )
142 case XML_ROOT_CONTEXT
:
143 if( nRecId
== BIFF12_ID_PCDEFINITION
) { mrPivotCache
.importPCDefinition( rStrm
); return this; }
146 case BIFF12_ID_PCDEFINITION
:
149 case BIFF12_ID_PCDSOURCE
: mrPivotCache
.importPCDSource( rStrm
); return this;
150 case BIFF12_ID_PCDFIELDS
: return this;
154 case BIFF12_ID_PCDSOURCE
:
155 if( nRecId
== BIFF12_ID_PCDSHEETSOURCE
) mrPivotCache
.importPCDSheetSource( rStrm
, getRelations() );
158 case BIFF12_ID_PCDFIELDS
:
159 if( nRecId
== BIFF12_ID_PCDFIELD
) return new PivotCacheFieldContext( *this, mrPivotCache
.createCacheField() );
165 const RecordInfo
* PivotCacheDefinitionFragment::getRecordInfos() const
167 static const RecordInfo spRecInfos
[] =
169 { BIFF12_ID_PCDEFINITION
, BIFF12_ID_PCDEFINITION
+ 1 },
170 { BIFF12_ID_PCDFDISCRETEPR
, BIFF12_ID_PCDFDISCRETEPR
+ 1 },
171 { BIFF12_ID_PCDFGROUPITEMS
, BIFF12_ID_PCDFGROUPITEMS
+ 1 },
172 { BIFF12_ID_PCDFIELD
, BIFF12_ID_PCDFIELD
+ 1 },
173 { BIFF12_ID_PCDFIELDGROUP
, BIFF12_ID_PCDFIELDGROUP
+ 1 },
174 { BIFF12_ID_PCDFIELDS
, BIFF12_ID_PCDFIELDS
+ 1 },
175 { BIFF12_ID_PCDFRANGEPR
, BIFF12_ID_PCDFRANGEPR
+ 1 },
176 { BIFF12_ID_PCDFSHAREDITEMS
, BIFF12_ID_PCDFSHAREDITEMS
+ 1 },
177 { BIFF12_ID_PCITEM_ARRAY
, BIFF12_ID_PCITEM_ARRAY
+ 1 },
178 { BIFF12_ID_PCDSHEETSOURCE
, BIFF12_ID_PCDSHEETSOURCE
+ 1 },
179 { BIFF12_ID_PCDSOURCE
, BIFF12_ID_PCDSOURCE
+ 1 },
185 void PivotCacheDefinitionFragment::finalizeImport()
187 // finalize the cache (check source range etc.)
188 mrPivotCache
.finalizeImport();
190 // load the cache records, if the cache is based on a deleted or an external worksheet
191 if( mrPivotCache
.isValidDataSource() && mrPivotCache
.isBasedOnDummySheet() )
193 OUString aRecFragmentPath
= getRelations().getFragmentPathFromRelId( mrPivotCache
.getRecordsRelId() );
194 if( !aRecFragmentPath
.isEmpty() )
196 SCTAB nSheet
= mrPivotCache
.getSourceRange().aStart
.Tab();
197 WorksheetGlobalsRef xSheetGlob
= WorksheetHelper::constructGlobals( *this, ISegmentProgressBarRef(), WorksheetType::Work
, nSheet
);
199 importOoxFragment( new PivotCacheRecordsFragment( *xSheetGlob
, aRecFragmentPath
, mrPivotCache
) );
204 PivotCacheRecordsFragment::PivotCacheRecordsFragment( const WorksheetHelper
& rHelper
,
205 const OUString
& rFragmentPath
, const PivotCache
& rPivotCache
) :
206 WorksheetFragmentBase( rHelper
, rFragmentPath
),
207 mrPivotCache( rPivotCache
),
212 sal_Int32 nSheetCount
= rPivotCache
.getWorksheets().getAllSheetCount();
214 // prepare sheet: insert column header names into top row
215 rPivotCache
.writeSourceHeaderCells( *this );
216 // resize formula buffers since we've added a new dummy sheet
217 rHelper
.getFormulaBuffer().SetSheetCount( nSheetCount
);
220 ContextHandlerRef
PivotCacheRecordsFragment::onCreateContext( sal_Int32 nElement
, const AttributeList
& rAttribs
)
222 switch( getCurrentElement() )
224 case XML_ROOT_CONTEXT
:
225 if( nElement
== XLS_TOKEN( pivotCacheRecords
) ) return this;
228 case XLS_TOKEN( pivotCacheRecords
):
229 if( nElement
== XLS_TOKEN( r
) ) { startCacheRecord(); return this; }
234 PivotCacheItem aItem
;
237 case XLS_TOKEN( m
): break;
238 case XLS_TOKEN( s
): aItem
.readString( rAttribs
); break;
239 case XLS_TOKEN( n
): aItem
.readNumeric( rAttribs
); break;
240 case XLS_TOKEN( d
): aItem
.readDate( rAttribs
); break;
241 case XLS_TOKEN( b
): aItem
.readBool( rAttribs
); break;
242 case XLS_TOKEN( e
): aItem
.readError( rAttribs
); break;
243 case XLS_TOKEN( x
): aItem
.readIndex( rAttribs
); break;
244 default: OSL_FAIL( "OoxPivotCacheRecordsFragment::onCreateContext - unexpected element" );
246 mrPivotCache
.writeSourceDataCell( *this, mnColIdx
, mnRowIdx
, aItem
);
254 ContextHandlerRef
PivotCacheRecordsFragment::onCreateRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
)
256 switch( getCurrentElement() )
258 case XML_ROOT_CONTEXT
:
259 if( nRecId
== BIFF12_ID_PCRECORDS
) return this;
262 case BIFF12_ID_PCRECORDS
:
265 case BIFF12_ID_PCRECORD
: importPCRecord( rStrm
); break;
266 case BIFF12_ID_PCRECORDDT
: startCacheRecord(); break;
267 default: importPCRecordItem( nRecId
, rStrm
); break;
274 const RecordInfo
* PivotCacheRecordsFragment::getRecordInfos() const
276 static const RecordInfo spRecInfos
[] =
278 { BIFF12_ID_PCRECORDS
, BIFF12_ID_PCRECORDS
+ 1 },
284 // private --------------------------------------------------------------------
286 void PivotCacheRecordsFragment::startCacheRecord()
293 void PivotCacheRecordsFragment::importPCRecord( SequenceInputStream
& rStrm
)
296 mrPivotCache
.importPCRecord( rStrm
, *this, mnRowIdx
);
300 void PivotCacheRecordsFragment::importPCRecordItem( sal_Int32 nRecId
, SequenceInputStream
& rStrm
)
305 PivotCacheItem aItem
;
308 case BIFF12_ID_PCITEM_MISSING
: break;
309 case BIFF12_ID_PCITEM_STRING
: aItem
.readString( rStrm
); break;
310 case BIFF12_ID_PCITEM_DOUBLE
: aItem
.readDouble( rStrm
); break;
311 case BIFF12_ID_PCITEM_DATE
: aItem
.readDate( rStrm
); break;
312 case BIFF12_ID_PCITEM_BOOL
: aItem
.readBool( rStrm
); break;
313 case BIFF12_ID_PCITEM_ERROR
: aItem
.readError( rStrm
, getUnitConverter() ); break;
314 case BIFF12_ID_PCITEM_INDEX
: aItem
.readIndex( rStrm
); break;
315 default: OSL_FAIL( "OoxPivotCacheRecordsFragment::importPCRecordItem - unexpected record" );
317 mrPivotCache
.writeSourceDataCell( *this, mnColIdx
, mnRowIdx
, aItem
);
322 } // namespace oox::xls
324 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */