summaryrefslogtreecommitdiffstats
path: root/sc/source/filter/oox/pivotcachefragment.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/oox/pivotcachefragment.cxx')
-rw-r--r--sc/source/filter/oox/pivotcachefragment.cxx325
1 files changed, 325 insertions, 0 deletions
diff --git a/sc/source/filter/oox/pivotcachefragment.cxx b/sc/source/filter/oox/pivotcachefragment.cxx
new file mode 100644
index 000000000..f508c36cf
--- /dev/null
+++ b/sc/source/filter/oox/pivotcachefragment.cxx
@@ -0,0 +1,325 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <pivotcachefragment.hxx>
+
+#include <osl/diagnose.h>
+#include <oox/token/namespaces.hxx>
+#include <biffhelper.hxx>
+#include <formulabuffer.hxx>
+#include <pivotcachebuffer.hxx>
+#include <worksheetbuffer.hxx>
+
+namespace oox::xls {
+
+using namespace ::com::sun::star::uno;
+using namespace ::oox::core;
+
+PivotCacheFieldContext::PivotCacheFieldContext( WorkbookFragmentBase& rFragment, PivotCacheField& rCacheField ) :
+ WorkbookContextBase( rFragment ),
+ mrCacheField( rCacheField )
+{
+}
+
+ContextHandlerRef PivotCacheFieldContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( cacheField ):
+ if( nElement == XLS_TOKEN( sharedItems ) ) { mrCacheField.importSharedItems( rAttribs ); return this; }
+ if( nElement == XLS_TOKEN( fieldGroup ) ) { mrCacheField.importFieldGroup( rAttribs ); return this; }
+ break;
+
+ case XLS_TOKEN( fieldGroup ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( rangePr ): mrCacheField.importRangePr( rAttribs ); break;
+ case XLS_TOKEN( discretePr ): return this;
+ case XLS_TOKEN( groupItems ): return this;
+ }
+ break;
+
+ case XLS_TOKEN( sharedItems ): mrCacheField.importSharedItem( nElement, rAttribs ); break;
+ case XLS_TOKEN( discretePr ): mrCacheField.importDiscretePrItem( nElement, rAttribs ); break;
+ case XLS_TOKEN( groupItems ): mrCacheField.importGroupItem( nElement, rAttribs ); break;
+ }
+ return nullptr;
+}
+
+void PivotCacheFieldContext::onStartElement( const AttributeList& rAttribs )
+{
+ if( isRootElement() )
+ mrCacheField.importCacheField( rAttribs );
+}
+
+ContextHandlerRef PivotCacheFieldContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case BIFF12_ID_PCDFIELD:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCDFSHAREDITEMS: mrCacheField.importPCDFSharedItems( rStrm ); return this;
+ case BIFF12_ID_PCDFIELDGROUP: mrCacheField.importPCDFieldGroup( rStrm ); return this;
+ }
+ break;
+
+ case BIFF12_ID_PCDFIELDGROUP:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCDFRANGEPR: mrCacheField.importPCDFRangePr( rStrm ); break;
+ case BIFF12_ID_PCDFDISCRETEPR: return this;
+ case BIFF12_ID_PCDFGROUPITEMS: return this;
+ }
+ break;
+
+ case BIFF12_ID_PCDFSHAREDITEMS: mrCacheField.importPCDFSharedItem( nRecId, rStrm ); break;
+ case BIFF12_ID_PCDFDISCRETEPR: mrCacheField.importPCDFDiscretePrItem( nRecId, rStrm ); break;
+ case BIFF12_ID_PCDFGROUPITEMS: mrCacheField.importPCDFGroupItem( nRecId, rStrm ); break;
+ }
+ return nullptr;
+}
+
+void PivotCacheFieldContext::onStartRecord( SequenceInputStream& rStrm )
+{
+ if( isRootElement() )
+ mrCacheField.importPCDField( rStrm );
+}
+
+PivotCacheDefinitionFragment::PivotCacheDefinitionFragment(
+ const WorkbookHelper& rHelper, const OUString& rFragmentPath, PivotCache& rPivotCache ) :
+ WorkbookFragmentBase( rHelper, rFragmentPath ),
+ mrPivotCache( rPivotCache )
+{
+}
+
+ContextHandlerRef PivotCacheDefinitionFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( pivotCacheDefinition ) ) { mrPivotCache.importPivotCacheDefinition( rAttribs ); return this; }
+ break;
+
+ case XLS_TOKEN( pivotCacheDefinition ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( cacheSource ): mrPivotCache.importCacheSource( rAttribs ); return this;
+ case XLS_TOKEN( cacheFields ): return this;
+ }
+ break;
+
+ case XLS_TOKEN( cacheSource ):
+ if( nElement == XLS_TOKEN( worksheetSource ) ) mrPivotCache.importWorksheetSource( rAttribs, getRelations() );
+ break;
+
+ case XLS_TOKEN( cacheFields ):
+ if( nElement == XLS_TOKEN( cacheField ) ) return new PivotCacheFieldContext( *this, mrPivotCache.createCacheField() );
+ break;
+ }
+ return nullptr;
+}
+
+ContextHandlerRef PivotCacheDefinitionFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_PCDEFINITION ) { mrPivotCache.importPCDefinition( rStrm ); return this; }
+ break;
+
+ case BIFF12_ID_PCDEFINITION:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCDSOURCE: mrPivotCache.importPCDSource( rStrm ); return this;
+ case BIFF12_ID_PCDFIELDS: return this;
+ }
+ break;
+
+ case BIFF12_ID_PCDSOURCE:
+ if( nRecId == BIFF12_ID_PCDSHEETSOURCE ) mrPivotCache.importPCDSheetSource( rStrm, getRelations() );
+ break;
+
+ case BIFF12_ID_PCDFIELDS:
+ if( nRecId == BIFF12_ID_PCDFIELD ) return new PivotCacheFieldContext( *this, mrPivotCache.createCacheField() );
+ break;
+ }
+ return nullptr;
+}
+
+const RecordInfo* PivotCacheDefinitionFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_PCDEFINITION, BIFF12_ID_PCDEFINITION + 1 },
+ { BIFF12_ID_PCDFDISCRETEPR, BIFF12_ID_PCDFDISCRETEPR + 1 },
+ { BIFF12_ID_PCDFGROUPITEMS, BIFF12_ID_PCDFGROUPITEMS + 1 },
+ { BIFF12_ID_PCDFIELD, BIFF12_ID_PCDFIELD + 1 },
+ { BIFF12_ID_PCDFIELDGROUP, BIFF12_ID_PCDFIELDGROUP + 1 },
+ { BIFF12_ID_PCDFIELDS, BIFF12_ID_PCDFIELDS + 1 },
+ { BIFF12_ID_PCDFRANGEPR, BIFF12_ID_PCDFRANGEPR + 1 },
+ { BIFF12_ID_PCDFSHAREDITEMS, BIFF12_ID_PCDFSHAREDITEMS + 1 },
+ { BIFF12_ID_PCITEM_ARRAY, BIFF12_ID_PCITEM_ARRAY + 1 },
+ { BIFF12_ID_PCDSHEETSOURCE, BIFF12_ID_PCDSHEETSOURCE + 1 },
+ { BIFF12_ID_PCDSOURCE, BIFF12_ID_PCDSOURCE + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+void PivotCacheDefinitionFragment::finalizeImport()
+{
+ // finalize the cache (check source range etc.)
+ mrPivotCache.finalizeImport();
+
+ // load the cache records, if the cache is based on a deleted or an external worksheet
+ if( mrPivotCache.isValidDataSource() && mrPivotCache.isBasedOnDummySheet() )
+ {
+ OUString aRecFragmentPath = getRelations().getFragmentPathFromRelId( mrPivotCache.getRecordsRelId() );
+ if( !aRecFragmentPath.isEmpty() )
+ {
+ SCTAB nSheet = mrPivotCache.getSourceRange().aStart.Tab();
+ WorksheetGlobalsRef xSheetGlob = WorksheetHelper::constructGlobals( *this, ISegmentProgressBarRef(), WorksheetType::Work, nSheet );
+ if( xSheetGlob )
+ importOoxFragment( new PivotCacheRecordsFragment( *xSheetGlob, aRecFragmentPath, mrPivotCache ) );
+ }
+ }
+}
+
+PivotCacheRecordsFragment::PivotCacheRecordsFragment( const WorksheetHelper& rHelper,
+ const OUString& rFragmentPath, const PivotCache& rPivotCache ) :
+ WorksheetFragmentBase( rHelper, rFragmentPath ),
+ mrPivotCache( rPivotCache ),
+ mnColIdx( 0 ),
+ mnRowIdx( 0 ),
+ mbInRecord( false )
+{
+ sal_Int32 nSheetCount = rPivotCache.getWorksheets().getAllSheetCount();
+
+ // prepare sheet: insert column header names into top row
+ rPivotCache.writeSourceHeaderCells( *this );
+ // resize formula buffers since we've added a new dummy sheet
+ rHelper.getFormulaBuffer().SetSheetCount( nSheetCount );
+}
+
+ContextHandlerRef PivotCacheRecordsFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( pivotCacheRecords ) ) return this;
+ break;
+
+ case XLS_TOKEN( pivotCacheRecords ):
+ if( nElement == XLS_TOKEN( r ) ) { startCacheRecord(); return this; }
+ break;
+
+ case XLS_TOKEN( r ):
+ {
+ PivotCacheItem aItem;
+ switch( nElement )
+ {
+ case XLS_TOKEN( m ): break;
+ case XLS_TOKEN( s ): aItem.readString( rAttribs ); break;
+ case XLS_TOKEN( n ): aItem.readNumeric( rAttribs ); break;
+ case XLS_TOKEN( d ): aItem.readDate( rAttribs ); break;
+ case XLS_TOKEN( b ): aItem.readBool( rAttribs ); break;
+ case XLS_TOKEN( e ): aItem.readError( rAttribs ); break;
+ case XLS_TOKEN( x ): aItem.readIndex( rAttribs ); break;
+ default: OSL_FAIL( "OoxPivotCacheRecordsFragment::onCreateContext - unexpected element" );
+ }
+ mrPivotCache.writeSourceDataCell( *this, mnColIdx, mnRowIdx, aItem );
+ ++mnColIdx;
+ }
+ break;
+ }
+ return nullptr;
+}
+
+ContextHandlerRef PivotCacheRecordsFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == BIFF12_ID_PCRECORDS ) return this;
+ break;
+
+ case BIFF12_ID_PCRECORDS:
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCRECORD: importPCRecord( rStrm ); break;
+ case BIFF12_ID_PCRECORDDT: startCacheRecord(); break;
+ default: importPCRecordItem( nRecId, rStrm ); break;
+ }
+ break;
+ }
+ return nullptr;
+}
+
+const RecordInfo* PivotCacheRecordsFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { BIFF12_ID_PCRECORDS, BIFF12_ID_PCRECORDS + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+// private --------------------------------------------------------------------
+
+void PivotCacheRecordsFragment::startCacheRecord()
+{
+ mnColIdx = 0;
+ ++mnRowIdx;
+ mbInRecord = true;
+}
+
+void PivotCacheRecordsFragment::importPCRecord( SequenceInputStream& rStrm )
+{
+ startCacheRecord();
+ mrPivotCache.importPCRecord( rStrm, *this, mnRowIdx );
+ mbInRecord = false;
+}
+
+void PivotCacheRecordsFragment::importPCRecordItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
+{
+ if( !mbInRecord )
+ return;
+
+ PivotCacheItem aItem;
+ switch( nRecId )
+ {
+ case BIFF12_ID_PCITEM_MISSING: break;
+ case BIFF12_ID_PCITEM_STRING: aItem.readString( rStrm ); break;
+ case BIFF12_ID_PCITEM_DOUBLE: aItem.readDouble( rStrm ); break;
+ case BIFF12_ID_PCITEM_DATE: aItem.readDate( rStrm ); break;
+ case BIFF12_ID_PCITEM_BOOL: aItem.readBool( rStrm ); break;
+ case BIFF12_ID_PCITEM_ERROR: aItem.readError( rStrm, getUnitConverter() ); break;
+ case BIFF12_ID_PCITEM_INDEX: aItem.readIndex( rStrm ); break;
+ default: OSL_FAIL( "OoxPivotCacheRecordsFragment::importPCRecordItem - unexpected record" );
+ }
+ mrPivotCache.writeSourceDataCell( *this, mnColIdx, mnRowIdx, aItem );
+ ++mnColIdx;
+}
+
+
+} // namespace oox::xls
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */