summaryrefslogtreecommitdiff
path: root/oox/source/xls/workbookfragment.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'oox/source/xls/workbookfragment.cxx')
-rw-r--r--oox/source/xls/workbookfragment.cxx706
1 files changed, 706 insertions, 0 deletions
diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx
new file mode 100644
index 000000000000..15b6e8a3e41e
--- /dev/null
+++ b/oox/source/xls/workbookfragment.cxx
@@ -0,0 +1,706 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: workbookfragment.cxx,v $
+ * $Revision: 1.4.20.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "oox/xls/workbookfragment.hxx"
+#include <com/sun/star/table/CellAddress.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/progressbar.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "oox/helper/recordinputstream.hxx"
+#include "oox/drawingml/themefragmenthandler.hxx"
+#include "oox/xls/biffinputstream.hxx"
+#include "oox/xls/chartsheetfragment.hxx"
+#include "oox/xls/connectionsfragment.hxx"
+#include "oox/xls/externallinkbuffer.hxx"
+#include "oox/xls/externallinkfragment.hxx"
+#include "oox/xls/pivotcachebuffer.hxx"
+#include "oox/xls/sharedstringsbuffer.hxx"
+#include "oox/xls/sharedstringsfragment.hxx"
+#include "oox/xls/stylesfragment.hxx"
+#include "oox/xls/tablebuffer.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/viewsettings.hxx"
+#include "oox/xls/workbooksettings.hxx"
+#include "oox/xls/worksheetbuffer.hxx"
+#include "oox/xls/worksheetfragment.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::table::CellAddress;
+using ::oox::core::ContextHandlerRef;
+using ::oox::core::FragmentHandlerRef;
+using ::oox::core::RecordInfo;
+using ::oox::core::Relation;
+using ::oox::drawingml::ThemeFragmentHandler;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+namespace {
+
+const double PROGRESS_LENGTH_GLOBALS = 0.1; /// 10% of progress bar for globals import.
+
+} // namespace
+
+// ============================================================================
+
+OoxWorkbookFragment::OoxWorkbookFragment(
+ const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
+ OoxWorkbookFragmentBase( rHelper, rFragmentPath )
+{
+}
+
+// oox.core.ContextHandler2Helper interface -----------------------------------
+
+ContextHandlerRef OoxWorkbookFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nElement == XLS_TOKEN( workbook ) ) return this;
+ break;
+
+ case XLS_TOKEN( workbook ):
+ switch( nElement )
+ {
+ case XLS_TOKEN( sheets ):
+ case XLS_TOKEN( bookViews ):
+ case XLS_TOKEN( externalReferences ):
+ case XLS_TOKEN( definedNames ):
+ case XLS_TOKEN( pivotCaches ): return this;
+
+ case XLS_TOKEN( workbookPr ): getWorkbookSettings().importWorkbookPr( rAttribs ); break;
+ case XLS_TOKEN( calcPr ): getWorkbookSettings().importCalcPr( rAttribs ); break;
+ }
+ break;
+
+ case XLS_TOKEN( sheets ):
+ if( nElement == XLS_TOKEN( sheet ) ) getWorksheets().importSheet( rAttribs );
+ break;
+ case XLS_TOKEN( bookViews ):
+ if( nElement == XLS_TOKEN( workbookView ) ) getViewSettings().importWorkbookView( rAttribs );
+ break;
+ case XLS_TOKEN( externalReferences ):
+ if( nElement == XLS_TOKEN( externalReference ) ) importExternalReference( rAttribs );
+ break;
+ case XLS_TOKEN( definedNames ):
+ if( nElement == XLS_TOKEN( definedName ) ) { importDefinedName( rAttribs ); return this; } // collect formula
+ break;
+ case XLS_TOKEN( pivotCaches ):
+ if( nElement == XLS_TOKEN( pivotCache ) ) importPivotCache( rAttribs );
+ break;
+ }
+ return 0;
+}
+
+void OoxWorkbookFragment::onEndElement( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ case XLS_TOKEN( definedName ):
+ if( mxCurrName.get() ) mxCurrName->setFormula( rChars );
+ break;
+ }
+}
+
+ContextHandlerRef OoxWorkbookFragment::onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ if( nRecId == OOBIN_ID_WORKBOOK ) return this;
+ break;
+
+ case OOBIN_ID_WORKBOOK:
+ switch( nRecId )
+ {
+ case OOBIN_ID_SHEETS:
+ case OOBIN_ID_BOOKVIEWS:
+ case OOBIN_ID_EXTERNALREFS:
+ case OOBIN_ID_PIVOTCACHES: return this;
+
+ case OOBIN_ID_WORKBOOKPR: getWorkbookSettings().importWorkbookPr( rStrm ); break;
+ case OOBIN_ID_CALCPR: getWorkbookSettings().importCalcPr( rStrm ); break;
+ case OOBIN_ID_DEFINEDNAME: getDefinedNames().importDefinedName( rStrm ); break;
+ }
+ break;
+
+ case OOBIN_ID_SHEETS:
+ if( nRecId == OOBIN_ID_SHEET ) getWorksheets().importSheet( rStrm );
+ break;
+ case OOBIN_ID_BOOKVIEWS:
+ if( nRecId == OOBIN_ID_WORKBOOKVIEW ) getViewSettings().importWorkbookView( rStrm );
+ break;
+
+ case OOBIN_ID_EXTERNALREFS:
+ switch( nRecId )
+ {
+ case OOBIN_ID_EXTERNALREF: importExternalRef( rStrm ); break;
+ case OOBIN_ID_EXTERNALSELF: getExternalLinks().importExternalSelf( rStrm ); break;
+ case OOBIN_ID_EXTERNALSAME: getExternalLinks().importExternalSame( rStrm ); break;
+ case OOBIN_ID_EXTERNALADDIN: getExternalLinks().importExternalAddin( rStrm ); break;
+ case OOBIN_ID_EXTERNALSHEETS: getExternalLinks().importExternalSheets( rStrm ); break;
+ }
+ break;
+
+ case OOBIN_ID_PIVOTCACHES:
+ if( nRecId == OOBIN_ID_PIVOTCACHE ) importPivotCache( rStrm );
+ }
+ return 0;
+}
+
+// oox.core.FragmentHandler2 interface ----------------------------------------
+
+const RecordInfo* OoxWorkbookFragment::getRecordInfos() const
+{
+ static const RecordInfo spRecInfos[] =
+ {
+ { OOBIN_ID_BOOKVIEWS, OOBIN_ID_BOOKVIEWS + 1 },
+ { OOBIN_ID_EXTERNALREFS, OOBIN_ID_EXTERNALREFS + 1 },
+ { OOBIN_ID_FUNCTIONGROUPS, OOBIN_ID_FUNCTIONGROUPS + 2 },
+ { OOBIN_ID_PIVOTCACHE, OOBIN_ID_PIVOTCACHE + 1 },
+ { OOBIN_ID_PIVOTCACHES, OOBIN_ID_PIVOTCACHES + 1 },
+ { OOBIN_ID_SHEETS, OOBIN_ID_SHEETS + 1 },
+ { OOBIN_ID_WORKBOOK, OOBIN_ID_WORKBOOK + 1 },
+ { -1, -1 }
+ };
+ return spRecInfos;
+}
+
+void OoxWorkbookFragment::finalizeImport()
+{
+ ISegmentProgressBarRef xGlobalSegment = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
+
+ // read the theme substream
+ OUString aThemeFragmentPath = getFragmentPathFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "theme" ) );
+ if( aThemeFragmentPath.getLength() > 0 )
+ importOoxFragment( new ThemeFragmentHandler( getFilter(), aThemeFragmentPath, getTheme() ) );
+ xGlobalSegment->setPosition( 0.25 );
+
+ // read the styles substream (requires finalized theme buffer)
+ OUString aStylesFragmentPath = getFragmentPathFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "styles" ) );
+ if( aStylesFragmentPath.getLength() > 0 )
+ importOoxFragment( new OoxStylesFragment( *this, aStylesFragmentPath ) );
+ xGlobalSegment->setPosition( 0.5 );
+
+ // read the shared string table substream (requires finalized styles buffer)
+ OUString aSstFragmentPath = getFragmentPathFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "sharedStrings" ) );
+ if( aSstFragmentPath.getLength() > 0 )
+ importOoxFragment( new OoxSharedStringsFragment( *this, aSstFragmentPath ) );
+ xGlobalSegment->setPosition( 0.75 );
+
+ // read the connections substream
+ OUString aConnFragmentPath = getFragmentPathFromType( CREATE_OFFICEDOC_RELATIONSTYPE( "connections" ) );
+ if( aConnFragmentPath.getLength() > 0 )
+ importOoxFragment( new OoxConnectionsFragment( *this, aConnFragmentPath ) );
+ xGlobalSegment->setPosition( 1.0 );
+
+ /* Create fragments for all sheets, before importing them. Needed to do
+ some preprocessing in the fragment constructors, e.g. loading the table
+ fragments for all sheets that are needed before the cell formulas are
+ loaded. */
+ typedef ::std::map< sal_Int32, FragmentHandlerRef > SheetFragmentMap;
+ SheetFragmentMap aSheetFragments;
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ sal_Int32 nSheetCount = rWorksheets.getSheetCount();
+ for( sal_Int32 nSheet = 0; nSheet < nSheetCount; ++nSheet )
+ {
+ if( const Relation* pRelation = getRelations().getRelationFromRelId( rWorksheets.getSheetRelId( nSheet ) ) )
+ {
+ // get fragment path of the sheet
+ OUString aFragmentPath = getFragmentPathFromTarget( pRelation->maTarget );
+ OSL_ENSURE( aFragmentPath.getLength() > 0, "OoxWorkbookFragment::finalizeImport - cannot access sheet fragment" );
+ if( aFragmentPath.getLength() > 0 )
+ {
+ ::rtl::Reference< OoxWorksheetFragmentBase > xFragment;
+ double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet);
+ ISegmentProgressBarRef xSheetSegment = getProgressBar().createSegment( fSegmentLength );
+
+ // create the fragment according to the sheet type
+ if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "worksheet" ) )
+ {
+ xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_WORKSHEET, nSheet ) );
+ }
+ else if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "chartsheet" ) )
+ {
+ xFragment.set( new OoxChartsheetFragment( *this, aFragmentPath, xSheetSegment, nSheet ) );
+ }
+ else if( (pRelation->maType == CREATE_MSOFFICE_RELATIONSTYPE( "xlMacrosheet" )) ||
+ (pRelation->maType == CREATE_MSOFFICE_RELATIONSTYPE( "xlIntlMacrosheet" )) )
+ {
+ xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_MACROSHEET, nSheet ) );
+ }
+ else if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "dialogsheet" ) )
+ {
+ xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_DIALOGSHEET, nSheet ) );
+ }
+
+ // insert the fragment into the map
+ OSL_ENSURE( xFragment.is(), "OoxWorkbookFragment::finalizeImport - unknown sheet type" );
+ OSL_ENSURE( !xFragment.is() || xFragment->isValidSheet(), "OoxWorkbookFragment::finalizeImport - missing sheet in document" );
+ if( xFragment.is() && xFragment->isValidSheet() )
+ aSheetFragments[ nSheet ].set( xFragment.get() );
+ }
+ }
+ }
+
+ // create all defined names and database ranges
+ getDefinedNames().finalizeImport();
+ getTables().finalizeImport();
+
+ // load all worksheets
+ for( sal_Int32 nSheet = 0; nSheet < nSheetCount; ++nSheet )
+ {
+ SheetFragmentMap::iterator aIt = aSheetFragments.find( nSheet );
+ if( aIt != aSheetFragments.end() )
+ {
+ OOX_LOADSAVE_TIMER( IMPORTSHEETFRAGMENT );
+ // import the sheet fragment
+ importOoxFragment( aIt->second );
+ // delete fragment object, will free all allocated sheet buffers
+ aSheetFragments.erase( aIt );
+ }
+ }
+
+ // final conversions, e.g. calculation settings and view settings
+ finalizeWorkbookImport();
+}
+
+// private --------------------------------------------------------------------
+
+void OoxWorkbookFragment::importExternalReference( const AttributeList& rAttribs )
+{
+ if( ExternalLink* pExtLink = getExternalLinks().importExternalReference( rAttribs ).get() )
+ importExternalLinkFragment( *pExtLink );
+}
+
+void OoxWorkbookFragment::importDefinedName( const AttributeList& rAttribs )
+{
+ mxCurrName = getDefinedNames().importDefinedName( rAttribs );
+}
+
+void OoxWorkbookFragment::importPivotCache( const AttributeList& rAttribs )
+{
+ sal_Int32 nCacheId = rAttribs.getInteger( XML_cacheId, -1 );
+ OUString aRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
+ importPivotCacheDefFragment( aRelId, nCacheId );
+}
+
+void OoxWorkbookFragment::importExternalRef( RecordInputStream& rStrm )
+{
+ if( ExternalLink* pExtLink = getExternalLinks().importExternalRef( rStrm ).get() )
+ importExternalLinkFragment( *pExtLink );
+}
+
+void OoxWorkbookFragment::importPivotCache( RecordInputStream& rStrm )
+{
+ sal_Int32 nCacheId = rStrm.readInt32();
+ OUString aRelId = rStrm.readString();
+ importPivotCacheDefFragment( aRelId, nCacheId );
+}
+
+void OoxWorkbookFragment::importExternalLinkFragment( ExternalLink& rExtLink )
+{
+ OUString aFragmentPath = getFragmentPathFromRelId( rExtLink.getRelId() );
+ if( aFragmentPath.getLength() > 0 )
+ importOoxFragment( new OoxExternalLinkFragment( *this, aFragmentPath, rExtLink ) );
+}
+
+void OoxWorkbookFragment::importPivotCacheDefFragment( const OUString& rRelId, sal_Int32 nCacheId )
+{
+ // pivot caches will be imported on demand, here we just store the fragment path in the buffer
+ getPivotCaches().registerPivotCacheFragment( nCacheId, getFragmentPathFromRelId( rRelId ) );
+}
+
+// ============================================================================
+
+BiffWorkbookFragment::BiffWorkbookFragment( const WorkbookHelper& rHelper, const OUString& rStrmName ) :
+ BiffWorkbookFragmentBase( rHelper, rStrmName )
+{
+}
+
+bool BiffWorkbookFragment::importFragment()
+{
+ bool bRet = false;
+
+ BiffFragmentType eFragment = startFragment( getBiff() );
+ switch( eFragment )
+ {
+ case BIFF_FRAGMENT_GLOBALS:
+ {
+ // import workbook globals fragment and create sheets in document
+ ISegmentProgressBarRef xGlobalsProgress = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
+ bRet = importGlobalsFragment( *xGlobalsProgress );
+ // load sheet fragments (do not return false in bRet on missing/broken sheets)
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ bool bNextSheet = bRet;
+ for( sal_Int32 nSheet = 0, nSheetCount = rWorksheets.getSheetCount(); bNextSheet && (nSheet < nSheetCount); ++nSheet )
+ {
+ // try to start a new sheet fragment
+ double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet);
+ ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength );
+ BiffFragmentType eSheetFragment = startFragment( getBiff() );
+ bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nSheet );
+ }
+ }
+ break;
+
+ case BIFF_FRAGMENT_WORKSPACE:
+ {
+ bRet = importWorkspaceFragment();
+ // sheets are embedded in workspace fragment, nothing to do here
+ }
+ break;
+
+ case BIFF_FRAGMENT_WORKSHEET:
+ case BIFF_FRAGMENT_CHARTSHEET:
+ case BIFF_FRAGMENT_MACROSHEET:
+ {
+ /* Single sheet without globals
+ - #i62752# possible in all BIFF versions
+ - do not return false in bRet on missing/broken sheets. */
+ getWorksheets().initializeSingleSheet();
+ importSheetFragment( getProgressBar(), eFragment, 0 );
+ // success, even if stream is broken
+ bRet = true;
+ }
+ break;
+
+ default:;
+ }
+
+ // final conversions, e.g. calculation settings and view settings
+ finalizeWorkbookImport();
+
+ return bRet;
+}
+
+bool BiffWorkbookFragment::importWorkspaceFragment()
+{
+ // enable workbook mode, has not been set yet in BIFF4 workspace files
+ setIsWorkbookFile();
+
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ bool bRet = true;
+
+ // import the workspace globals
+ ISegmentProgressBarRef xGlobalsProgress = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
+ bool bLoop = true;
+ while( bRet && bLoop && mrStrm.startNextRecord() && (mrStrm.getRecId() != BIFF_ID_EOF) )
+ {
+ switch( mrStrm.getRecId() )
+ {
+ case BIFF_ID_SHEET: rWorksheets.importSheet( mrStrm ); break;
+ case BIFF_ID_CODEPAGE: setCodePage( mrStrm.readuInt16() ); break;
+ case BIFF_ID_FILEPASS: bRet = getCodecHelper().importFilePass( mrStrm ); break;
+ case BIFF_ID_SHEETHEADER: mrStrm.rewindRecord(); bLoop = false; break;
+ }
+ }
+ xGlobalsProgress->setPosition( 1.0 );
+
+ // load sheet fragments (do not return false in bRet on missing/broken sheets)
+ bool bNextSheet = bRet;
+ for( sal_Int32 nSheet = 0, nSheetCount = rWorksheets.getSheetCount(); bNextSheet && (nSheet < nSheetCount); ++nSheet )
+ {
+ // try to start a new sheet fragment (with leading SHEETHEADER record)
+ bNextSheet = mrStrm.startNextRecord() && (mrStrm.getRecId() == BIFF_ID_SHEETHEADER);
+ if( bNextSheet )
+ {
+ double fSegmentLength = getProgressBar().getFreeLength() / (nSheetCount - nSheet);
+ ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength );
+ /* Read current sheet name (sheet substreams may not be in the
+ same order as SHEET records are). */
+ mrStrm.skip( 4 );
+ OUString aSheetName = mrStrm.readByteString( false, getTextEncoding() );
+ sal_Int32 nCurrSheet = rWorksheets.getCalcSheetIndex( aSheetName );
+ // load the sheet fragment records
+ BiffFragmentType eSheetFragment = startFragment( getBiff() );
+ bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCurrSheet );
+ // do not return false in bRet on missing/broken sheets
+ }
+ }
+
+ return bRet;
+}
+
+bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgressBar )
+{
+ WorkbookSettings& rWorkbookSett = getWorkbookSettings();
+ ViewSettings& rViewSett = getViewSettings();
+ SharedStringsBuffer& rSharedStrings = getSharedStrings();
+ StylesBuffer& rStyles = getStyles();
+ WorksheetBuffer& rWorksheets = getWorksheets();
+ PivotCacheBuffer& rPivotCaches = getPivotCaches();
+
+ // collect records that need to be loaded in a second pass
+ typedef ::std::vector< sal_Int64 > RecordHandleVec;
+ RecordHandleVec aExtLinkRecs;
+
+ bool bRet = true;
+ bool bLoop = true;
+ while( bRet && bLoop && mrStrm.startNextRecord() )
+ {
+ sal_uInt16 nRecId = mrStrm.getRecId();
+ bool bExtLinkRec = false;
+
+ /* #i56376# BIFF5-BIFF8: If an EOF record for globals is missing,
+ simulate it. The issue is about a document where the sheet fragment
+ starts directly after the EXTSST record, without terminating the
+ globals fragment with an EOF record. */
+ if( isBofRecord() || (nRecId == BIFF_ID_EOF) )
+ {
+ bLoop = false;
+ }
+ else switch( nRecId )
+ {
+ // records in all BIFF versions
+ case BIFF_ID_CODEPAGE: setCodePage( mrStrm.readuInt16() ); break;
+ case BIFF_ID_DATEMODE: rWorkbookSett.importDateMode( mrStrm ); break;
+ case BIFF_ID_FILEPASS: bRet = getCodecHelper().importFilePass( mrStrm ); break;
+ case BIFF_ID_PRECISION: rWorkbookSett.importPrecision( mrStrm ); break;
+ case BIFF_ID_WINDOW1: rViewSett.importWindow1( mrStrm ); break;
+
+ // BIFF specific records
+ default: switch( getBiff() )
+ {
+ case BIFF2: switch( nRecId )
+ {
+ case BIFF2_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF2_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF2_ID_FONT: rStyles.importFont( mrStrm ); break;
+ case BIFF_ID_FONTCOLOR: rStyles.importFontColor( mrStrm ); break;
+ case BIFF2_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
+ case BIFF2_ID_XF: rStyles.importXf( mrStrm ); break;
+ }
+ break;
+
+ case BIFF3: switch( nRecId )
+ {
+ case BIFF_ID_CRN: bExtLinkRec = true; break;
+ case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF3_ID_FONT: rStyles.importFont( mrStrm ); break;
+ case BIFF2_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
+ case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break;
+ case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break;
+ case BIFF_ID_XCT: bExtLinkRec = true; break;
+ case BIFF3_ID_XF: rStyles.importXf( mrStrm ); break;
+ }
+ break;
+
+ case BIFF4: switch( nRecId )
+ {
+ case BIFF_ID_CRN: bExtLinkRec = true; break;
+ case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF3_ID_FONT: rStyles.importFont( mrStrm ); break;
+ case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
+ case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break;
+ case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break;
+ case BIFF_ID_XCT: bExtLinkRec = true; break;
+ case BIFF4_ID_XF: rStyles.importXf( mrStrm ); break;
+ }
+ break;
+
+ case BIFF5: switch( nRecId )
+ {
+ case BIFF_ID_BOOKBOOL: rWorkbookSett.importBookBool( mrStrm ); break;
+ case BIFF_ID_CRN: bExtLinkRec = true; break;
+ case BIFF5_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF5_ID_FONT: rStyles.importFont( mrStrm ); break;
+ case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
+ case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break;
+ case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( mrStrm ); break;
+ case BIFF_ID_SHEET: rWorksheets.importSheet( mrStrm ); break;
+ case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break;
+ case BIFF_ID_XCT: bExtLinkRec = true; break;
+ case BIFF5_ID_XF: rStyles.importXf( mrStrm ); break;
+ }
+ break;
+
+ case BIFF8: switch( nRecId )
+ {
+ case BIFF_ID_BOOKBOOL: rWorkbookSett.importBookBool( mrStrm ); break;
+ case BIFF_ID_CODENAME: rWorkbookSett.importCodeName( mrStrm ); break;
+ case BIFF_ID_CRN: bExtLinkRec = true; break;
+ case BIFF5_ID_DEFINEDNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNALBOOK: bExtLinkRec = true; break;
+ case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break;
+ case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
+ case BIFF5_ID_FONT: rStyles.importFont( mrStrm ); break;
+ case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
+ case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break;
+ case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break;
+ case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( mrStrm ); break;
+ case BIFF_ID_SHEET: rWorksheets.importSheet( mrStrm ); break;
+ case BIFF_ID_SST: rSharedStrings.importSst( mrStrm ); break;
+ case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break;
+ case BIFF_ID_USESELFS: rWorkbookSett.importUsesElfs( mrStrm ); break;
+ case BIFF_ID_XCT: bExtLinkRec = true; break;
+ case BIFF5_ID_XF: rStyles.importXf( mrStrm ); break;
+ }
+ break;
+
+ case BIFF_UNKNOWN: break;
+ }
+ }
+
+ if( bExtLinkRec )
+ aExtLinkRecs.push_back( mrStrm.getRecHandle() );
+ }
+
+ // finalize global buffers
+ rProgressBar.setPosition( 0.5 );
+ rSharedStrings.finalizeImport();
+ rStyles.finalizeImport();
+
+ /* Import external link data (EXTERNSHEET, EXTERNALNAME, DEFINEDNAME)
+ which need existing internal sheets (SHEET records). The SHEET records
+ may follow the external links records in some BIFF versions. */
+ if( bRet && !aExtLinkRecs.empty() )
+ {
+ // remember current stream position (the EOF record)
+ sal_Int64 nEofHandle = mrStrm.getRecHandle();
+ // this fragment class implements import of external link records
+ BiffExternalLinkFragment aLinkFragment( *this, true );
+ // import all records by using their cached record handle
+ for( RecordHandleVec::const_iterator aIt = aExtLinkRecs.begin(), aEnd = aExtLinkRecs.end(); (aIt != aEnd) && mrStrm.startRecordByHandle( *aIt ); ++aIt )
+ aLinkFragment.importRecord();
+ // finalize global buffers
+ aLinkFragment.finalizeImport();
+ // seek back to the EOF record of the workbook globals fragment
+ bRet = mrStrm.startRecordByHandle( nEofHandle );
+ }
+
+ // #i56376# missing EOF - rewind before worksheet BOF record (see above)
+ if( bRet && isBofRecord() )
+ mrStrm.rewindRecord();
+
+ rProgressBar.setPosition( 1.0 );
+ return bRet;
+}
+
+bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBar, BiffFragmentType eFragment, sal_Int32 nSheet )
+{
+ // find the sheet type for this fragment
+ WorksheetType eSheetType = SHEETTYPE_EMPTYSHEET;
+ switch( eFragment )
+ {
+ case BIFF_FRAGMENT_WORKSHEET: eSheetType = SHEETTYPE_WORKSHEET; break;
+ case BIFF_FRAGMENT_CHARTSHEET: eSheetType = SHEETTYPE_CHARTSHEET; break;
+ case BIFF_FRAGMENT_MACROSHEET: eSheetType = SHEETTYPE_MACROSHEET; break;
+ case BIFF_FRAGMENT_MODULESHEET: eSheetType = SHEETTYPE_MODULESHEET; break;
+ case BIFF_FRAGMENT_EMPTYSHEET: eSheetType = SHEETTYPE_EMPTYSHEET; break;
+ default: return false;
+ }
+
+ /* #i11183# Clear buffers that are used per-sheet, e.g. external links in
+ BIFF4W and BIFF5 files, or defined names in BIFF4W files. */
+ createBuffersPerSheet();
+
+ // preprocess some records
+ switch( getBiff() )
+ {
+ // load the workbook globals fragment records in BIFF2-BIFF4
+ case BIFF2:
+ case BIFF3:
+ case BIFF4:
+ {
+ // set sheet index in defined names buffer to handle built-in names correctly
+ getDefinedNames().setLocalSheetIndex( nSheet );
+ // remember current record to seek back below
+ sal_Int64 nRecHandle = mrStrm.getRecHandle();
+ // import the global records
+ ISegmentProgressBarRef xGlobalsProgress = rProgressBar.createSegment( PROGRESS_LENGTH_GLOBALS );
+ importGlobalsFragment( *xGlobalsProgress );
+ // rewind stream to fragment BOF record
+ mrStrm.startRecordByHandle( nRecHandle );
+ }
+ break;
+
+ // load the external link records for this sheet in BIFF5
+ case BIFF5:
+ {
+ // remember current record to seek back below
+ sal_Int64 nRecHandle = mrStrm.getRecHandle();
+ // fragment implementing import of external link records
+ BiffExternalLinkFragment( *this, false ).importFragment();
+ // rewind stream to fragment BOF record
+ mrStrm.startRecordByHandle( nRecHandle );
+ }
+ break;
+
+ case BIFF8:
+ break;
+
+ case BIFF_UNKNOWN:
+ break;
+ }
+
+ // create the worksheet fragment
+ ISegmentProgressBarRef xSheetProgress = rProgressBar.createSegment( rProgressBar.getFreeLength() );
+ ::boost::shared_ptr< BiffWorksheetFragmentBase > xFragment;
+ switch( eSheetType )
+ {
+ case SHEETTYPE_WORKSHEET:
+ case SHEETTYPE_MACROSHEET:
+ case SHEETTYPE_DIALOGSHEET:
+ xFragment.reset( new BiffWorksheetFragment( *this, xSheetProgress, eSheetType, nSheet ) );
+ break;
+ case SHEETTYPE_CHARTSHEET:
+ xFragment.reset( new BiffChartsheetFragment( *this, xSheetProgress, nSheet ) );
+ break;
+ case SHEETTYPE_MODULESHEET:
+ case SHEETTYPE_EMPTYSHEET:
+ xFragment.reset( new BiffSkipWorksheetFragment( *this, xSheetProgress, nSheet ) );
+ break;
+ }
+ // load the sheet fragment records
+ return xFragment->isValidSheet() && xFragment->importFragment();
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+