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>
32 using namespace ::com::sun::star::uno
;
33 using namespace ::oox::core
;
35 PivotCacheFieldContext::PivotCacheFieldContext( WorkbookFragmentBase
& rFragment
, PivotCacheField
& rCacheField
) :
36 WorkbookContextBase( rFragment
),
37 mrCacheField( rCacheField
)
41 ContextHandlerRef
PivotCacheFieldContext::onCreateContext( sal_Int32 nElement
, const AttributeList
& rAttribs
)
43 switch( getCurrentElement() )
45 case XLS_TOKEN( cacheField
):
46 if( nElement
== XLS_TOKEN( sharedItems
) ) { mrCacheField
.importSharedItems( rAttribs
); return this; }
47 if( nElement
== XLS_TOKEN( fieldGroup
) ) { mrCacheField
.importFieldGroup( rAttribs
); return this; }
50 case XLS_TOKEN( fieldGroup
):
53 case XLS_TOKEN( rangePr
): mrCacheField
.importRangePr( rAttribs
); break;
54 case XLS_TOKEN( discretePr
): return this;
55 case XLS_TOKEN( groupItems
): return this;
59 case XLS_TOKEN( sharedItems
): mrCacheField
.importSharedItem( nElement
, rAttribs
); break;
60 case XLS_TOKEN( discretePr
): mrCacheField
.importDiscretePrItem( nElement
, rAttribs
); break;
61 case XLS_TOKEN( groupItems
): mrCacheField
.importGroupItem( nElement
, rAttribs
); break;
66 void PivotCacheFieldContext::onStartElement( const AttributeList
& rAttribs
)
69 mrCacheField
.importCacheField( rAttribs
);
72 ContextHandlerRef
PivotCacheFieldContext::onCreateRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
)
74 switch( getCurrentElement() )
76 case BIFF12_ID_PCDFIELD
:
79 case BIFF12_ID_PCDFSHAREDITEMS
: mrCacheField
.importPCDFSharedItems( rStrm
); return this;
80 case BIFF12_ID_PCDFIELDGROUP
: mrCacheField
.importPCDFieldGroup( rStrm
); return this;
84 case BIFF12_ID_PCDFIELDGROUP
:
87 case BIFF12_ID_PCDFRANGEPR
: mrCacheField
.importPCDFRangePr( rStrm
); break;
88 case BIFF12_ID_PCDFDISCRETEPR
: return this;
89 case BIFF12_ID_PCDFGROUPITEMS
: return this;
93 case BIFF12_ID_PCDFSHAREDITEMS
: mrCacheField
.importPCDFSharedItem( nRecId
, rStrm
); break;
94 case BIFF12_ID_PCDFDISCRETEPR
: mrCacheField
.importPCDFDiscretePrItem( nRecId
, rStrm
); break;
95 case BIFF12_ID_PCDFGROUPITEMS
: mrCacheField
.importPCDFGroupItem( nRecId
, rStrm
); break;
100 void PivotCacheFieldContext::onStartRecord( SequenceInputStream
& rStrm
)
102 if( isRootElement() )
103 mrCacheField
.importPCDField( rStrm
);
106 PivotCacheDefinitionFragment::PivotCacheDefinitionFragment(
107 const WorkbookHelper
& rHelper
, const OUString
& rFragmentPath
, PivotCache
& rPivotCache
) :
108 WorkbookFragmentBase( rHelper
, rFragmentPath
),
109 mrPivotCache( rPivotCache
)
113 ContextHandlerRef
PivotCacheDefinitionFragment::onCreateContext( sal_Int32 nElement
, const AttributeList
& rAttribs
)
115 switch( getCurrentElement() )
117 case XML_ROOT_CONTEXT
:
118 if( nElement
== XLS_TOKEN( pivotCacheDefinition
) ) { mrPivotCache
.importPivotCacheDefinition( rAttribs
); return this; }
121 case XLS_TOKEN( pivotCacheDefinition
):
124 case XLS_TOKEN( cacheSource
): mrPivotCache
.importCacheSource( rAttribs
); return this;
125 case XLS_TOKEN( cacheFields
): return this;
129 case XLS_TOKEN( cacheSource
):
130 if( nElement
== XLS_TOKEN( worksheetSource
) ) mrPivotCache
.importWorksheetSource( rAttribs
, getRelations() );
133 case XLS_TOKEN( cacheFields
):
134 if( nElement
== XLS_TOKEN( cacheField
) ) return new PivotCacheFieldContext( *this, mrPivotCache
.createCacheField() );
140 ContextHandlerRef
PivotCacheDefinitionFragment::onCreateRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
)
142 switch( getCurrentElement() )
144 case XML_ROOT_CONTEXT
:
145 if( nRecId
== BIFF12_ID_PCDEFINITION
) { mrPivotCache
.importPCDefinition( rStrm
); return this; }
148 case BIFF12_ID_PCDEFINITION
:
151 case BIFF12_ID_PCDSOURCE
: mrPivotCache
.importPCDSource( rStrm
); return this;
152 case BIFF12_ID_PCDFIELDS
: return this;
156 case BIFF12_ID_PCDSOURCE
:
157 if( nRecId
== BIFF12_ID_PCDSHEETSOURCE
) mrPivotCache
.importPCDSheetSource( rStrm
, getRelations() );
160 case BIFF12_ID_PCDFIELDS
:
161 if( nRecId
== BIFF12_ID_PCDFIELD
) return new PivotCacheFieldContext( *this, mrPivotCache
.createCacheField() );
167 const RecordInfo
* PivotCacheDefinitionFragment::getRecordInfos() const
169 static const RecordInfo spRecInfos
[] =
171 { BIFF12_ID_PCDEFINITION
, BIFF12_ID_PCDEFINITION
+ 1 },
172 { BIFF12_ID_PCDFDISCRETEPR
, BIFF12_ID_PCDFDISCRETEPR
+ 1 },
173 { BIFF12_ID_PCDFGROUPITEMS
, BIFF12_ID_PCDFGROUPITEMS
+ 1 },
174 { BIFF12_ID_PCDFIELD
, BIFF12_ID_PCDFIELD
+ 1 },
175 { BIFF12_ID_PCDFIELDGROUP
, BIFF12_ID_PCDFIELDGROUP
+ 1 },
176 { BIFF12_ID_PCDFIELDS
, BIFF12_ID_PCDFIELDS
+ 1 },
177 { BIFF12_ID_PCDFRANGEPR
, BIFF12_ID_PCDFRANGEPR
+ 1 },
178 { BIFF12_ID_PCDFSHAREDITEMS
, BIFF12_ID_PCDFSHAREDITEMS
+ 1 },
179 { BIFF12_ID_PCITEM_ARRAY
, BIFF12_ID_PCITEM_ARRAY
+ 1 },
180 { BIFF12_ID_PCDSHEETSOURCE
, BIFF12_ID_PCDSHEETSOURCE
+ 1 },
181 { BIFF12_ID_PCDSOURCE
, BIFF12_ID_PCDSOURCE
+ 1 },
187 void PivotCacheDefinitionFragment::finalizeImport()
189 // finalize the cache (check source range etc.)
190 mrPivotCache
.finalizeImport();
192 // load the cache records, if the cache is based on a deleted or an external worksheet
193 if( mrPivotCache
.isValidDataSource() && mrPivotCache
.isBasedOnDummySheet() )
195 OUString aRecFragmentPath
= getRelations().getFragmentPathFromRelId( mrPivotCache
.getRecordsRelId() );
196 if( !aRecFragmentPath
.isEmpty() )
198 SCTAB nSheet
= mrPivotCache
.getSourceRange().aStart
.Tab();
199 WorksheetGlobalsRef xSheetGlob
= WorksheetHelper::constructGlobals( *this, ISegmentProgressBarRef(), WorksheetType::Work
, nSheet
);
200 if( xSheetGlob
.get() )
201 importOoxFragment( new PivotCacheRecordsFragment( *xSheetGlob
, aRecFragmentPath
, mrPivotCache
) );
206 PivotCacheRecordsFragment::PivotCacheRecordsFragment( const WorksheetHelper
& rHelper
,
207 const OUString
& rFragmentPath
, const PivotCache
& rPivotCache
) :
208 WorksheetFragmentBase( rHelper
, rFragmentPath
),
209 mrPivotCache( rPivotCache
),
214 sal_Int32 nSheetCount
= rPivotCache
.getWorksheets().getAllSheetCount();
216 // prepare sheet: insert column header names into top row
217 rPivotCache
.writeSourceHeaderCells( *this );
218 // resize formula buffers since we've added a new dummy sheet
219 rHelper
.getFormulaBuffer().SetSheetCount( nSheetCount
);
222 ContextHandlerRef
PivotCacheRecordsFragment::onCreateContext( sal_Int32 nElement
, const AttributeList
& rAttribs
)
224 switch( getCurrentElement() )
226 case XML_ROOT_CONTEXT
:
227 if( nElement
== XLS_TOKEN( pivotCacheRecords
) ) return this;
230 case XLS_TOKEN( pivotCacheRecords
):
231 if( nElement
== XLS_TOKEN( r
) ) { startCacheRecord(); return this; }
236 PivotCacheItem aItem
;
239 case XLS_TOKEN( m
): break;
240 case XLS_TOKEN( s
): aItem
.readString( rAttribs
); break;
241 case XLS_TOKEN( n
): aItem
.readNumeric( rAttribs
); break;
242 case XLS_TOKEN( d
): aItem
.readDate( rAttribs
); break;
243 case XLS_TOKEN( b
): aItem
.readBool( rAttribs
); break;
244 case XLS_TOKEN( e
): aItem
.readError( rAttribs
); break;
245 case XLS_TOKEN( x
): aItem
.readIndex( rAttribs
); break;
246 default: OSL_FAIL( "OoxPivotCacheRecordsFragment::onCreateContext - unexpected element" );
248 mrPivotCache
.writeSourceDataCell( *this, mnColIdx
, mnRowIdx
, aItem
);
256 ContextHandlerRef
PivotCacheRecordsFragment::onCreateRecordContext( sal_Int32 nRecId
, SequenceInputStream
& rStrm
)
258 switch( getCurrentElement() )
260 case XML_ROOT_CONTEXT
:
261 if( nRecId
== BIFF12_ID_PCRECORDS
) return this;
264 case BIFF12_ID_PCRECORDS
:
267 case BIFF12_ID_PCRECORD
: importPCRecord( rStrm
); break;
268 case BIFF12_ID_PCRECORDDT
: startCacheRecord(); break;
269 default: importPCRecordItem( nRecId
, rStrm
); break;
276 const RecordInfo
* PivotCacheRecordsFragment::getRecordInfos() const
278 static const RecordInfo spRecInfos
[] =
280 { BIFF12_ID_PCRECORDS
, BIFF12_ID_PCRECORDS
+ 1 },
286 // private --------------------------------------------------------------------
288 void PivotCacheRecordsFragment::startCacheRecord()
295 void PivotCacheRecordsFragment::importPCRecord( SequenceInputStream
& rStrm
)
298 mrPivotCache
.importPCRecord( rStrm
, *this, mnRowIdx
);
302 void PivotCacheRecordsFragment::importPCRecordItem( sal_Int32 nRecId
, SequenceInputStream
& rStrm
)
306 PivotCacheItem aItem
;
309 case BIFF12_ID_PCITEM_MISSING
: break;
310 case BIFF12_ID_PCITEM_STRING
: aItem
.readString( rStrm
); break;
311 case BIFF12_ID_PCITEM_DOUBLE
: aItem
.readDouble( rStrm
); break;
312 case BIFF12_ID_PCITEM_DATE
: aItem
.readDate( rStrm
); break;
313 case BIFF12_ID_PCITEM_BOOL
: aItem
.readBool( rStrm
); break;
314 case BIFF12_ID_PCITEM_ERROR
: aItem
.readError( rStrm
); break;
315 case BIFF12_ID_PCITEM_INDEX
: aItem
.readIndex( rStrm
); break;
316 default: OSL_FAIL( "OoxPivotCacheRecordsFragment::importPCRecordItem - unexpected record" );
318 mrPivotCache
.writeSourceDataCell( *this, mnColIdx
, mnRowIdx
, aItem
);
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */