Update ooo320-m1
[ooovba.git] / oox / source / xls / workbookfragment.cxx
bloba372ef7146335b56c029d6e2c282ca8e13e340d0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: workbookfragment.cxx,v $
10 * $Revision: 1.4.20.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/xls/workbookfragment.hxx"
32 #include <com/sun/star/table/CellAddress.hpp>
33 #include "oox/helper/attributelist.hxx"
34 #include "oox/helper/progressbar.hxx"
35 #include "oox/helper/propertyset.hxx"
36 #include "oox/helper/recordinputstream.hxx"
37 #include "oox/drawingml/themefragmenthandler.hxx"
38 #include "oox/xls/biffinputstream.hxx"
39 #include "oox/xls/chartsheetfragment.hxx"
40 #include "oox/xls/connectionsfragment.hxx"
41 #include "oox/xls/externallinkbuffer.hxx"
42 #include "oox/xls/externallinkfragment.hxx"
43 #include "oox/xls/pivotcachebuffer.hxx"
44 #include "oox/xls/sharedstringsbuffer.hxx"
45 #include "oox/xls/sharedstringsfragment.hxx"
46 #include "oox/xls/stylesfragment.hxx"
47 #include "oox/xls/tablebuffer.hxx"
48 #include "oox/xls/themebuffer.hxx"
49 #include "oox/xls/viewsettings.hxx"
50 #include "oox/xls/workbooksettings.hxx"
51 #include "oox/xls/worksheetbuffer.hxx"
52 #include "oox/xls/worksheetfragment.hxx"
54 using ::rtl::OUString;
55 using ::com::sun::star::uno::Reference;
56 using ::com::sun::star::uno::Exception;
57 using ::com::sun::star::uno::UNO_QUERY;
58 using ::com::sun::star::uno::UNO_QUERY_THROW;
59 using ::com::sun::star::table::CellAddress;
60 using ::oox::core::ContextHandlerRef;
61 using ::oox::core::FragmentHandlerRef;
62 using ::oox::core::RecordInfo;
63 using ::oox::core::Relation;
64 using ::oox::drawingml::ThemeFragmentHandler;
66 namespace oox {
67 namespace xls {
69 // ============================================================================
71 namespace {
73 const double PROGRESS_LENGTH_GLOBALS = 0.1; /// 10% of progress bar for globals import.
75 } // namespace
77 // ============================================================================
79 OoxWorkbookFragment::OoxWorkbookFragment(
80 const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
81 OoxWorkbookFragmentBase( rHelper, rFragmentPath )
85 // oox.core.ContextHandler2Helper interface -----------------------------------
87 ContextHandlerRef OoxWorkbookFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
89 switch( getCurrentElement() )
91 case XML_ROOT_CONTEXT:
92 if( nElement == XLS_TOKEN( workbook ) ) return this;
93 break;
95 case XLS_TOKEN( workbook ):
96 switch( nElement )
98 case XLS_TOKEN( sheets ):
99 case XLS_TOKEN( bookViews ):
100 case XLS_TOKEN( externalReferences ):
101 case XLS_TOKEN( definedNames ):
102 case XLS_TOKEN( pivotCaches ): return this;
104 case XLS_TOKEN( fileSharing ): getWorkbookSettings().importFileSharing( rAttribs ); break;
105 case XLS_TOKEN( workbookPr ): getWorkbookSettings().importWorkbookPr( rAttribs ); break;
106 case XLS_TOKEN( calcPr ): getWorkbookSettings().importCalcPr( rAttribs ); break;
108 break;
110 case XLS_TOKEN( sheets ):
111 if( nElement == XLS_TOKEN( sheet ) ) getWorksheets().importSheet( rAttribs );
112 break;
113 case XLS_TOKEN( bookViews ):
114 if( nElement == XLS_TOKEN( workbookView ) ) getViewSettings().importWorkbookView( rAttribs );
115 break;
116 case XLS_TOKEN( externalReferences ):
117 if( nElement == XLS_TOKEN( externalReference ) ) importExternalReference( rAttribs );
118 break;
119 case XLS_TOKEN( definedNames ):
120 if( nElement == XLS_TOKEN( definedName ) ) { importDefinedName( rAttribs ); return this; } // collect formula
121 break;
122 case XLS_TOKEN( pivotCaches ):
123 if( nElement == XLS_TOKEN( pivotCache ) ) importPivotCache( rAttribs );
124 break;
126 return 0;
129 void OoxWorkbookFragment::onEndElement( const OUString& rChars )
131 switch( getCurrentElement() )
133 case XLS_TOKEN( definedName ):
134 if( mxCurrName.get() ) mxCurrName->setFormula( rChars );
135 break;
139 ContextHandlerRef OoxWorkbookFragment::onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm )
141 switch( getCurrentElement() )
143 case XML_ROOT_CONTEXT:
144 if( nRecId == OOBIN_ID_WORKBOOK ) return this;
145 break;
147 case OOBIN_ID_WORKBOOK:
148 switch( nRecId )
150 case OOBIN_ID_SHEETS:
151 case OOBIN_ID_BOOKVIEWS:
152 case OOBIN_ID_EXTERNALREFS:
153 case OOBIN_ID_PIVOTCACHES: return this;
155 case OOBIN_ID_FILESHARING: getWorkbookSettings().importFileSharing( rStrm ); break;
156 case OOBIN_ID_WORKBOOKPR: getWorkbookSettings().importWorkbookPr( rStrm ); break;
157 case OOBIN_ID_CALCPR: getWorkbookSettings().importCalcPr( rStrm ); break;
158 case OOBIN_ID_DEFINEDNAME: getDefinedNames().importDefinedName( rStrm ); break;
160 break;
162 case OOBIN_ID_SHEETS:
163 if( nRecId == OOBIN_ID_SHEET ) getWorksheets().importSheet( rStrm );
164 break;
165 case OOBIN_ID_BOOKVIEWS:
166 if( nRecId == OOBIN_ID_WORKBOOKVIEW ) getViewSettings().importWorkbookView( rStrm );
167 break;
169 case OOBIN_ID_EXTERNALREFS:
170 switch( nRecId )
172 case OOBIN_ID_EXTERNALREF: importExternalRef( rStrm ); break;
173 case OOBIN_ID_EXTERNALSELF: getExternalLinks().importExternalSelf( rStrm ); break;
174 case OOBIN_ID_EXTERNALSAME: getExternalLinks().importExternalSame( rStrm ); break;
175 case OOBIN_ID_EXTERNALADDIN: getExternalLinks().importExternalAddin( rStrm ); break;
176 case OOBIN_ID_EXTERNALSHEETS: getExternalLinks().importExternalSheets( rStrm ); break;
178 break;
180 case OOBIN_ID_PIVOTCACHES:
181 if( nRecId == OOBIN_ID_PIVOTCACHE ) importPivotCache( rStrm );
183 return 0;
186 // oox.core.FragmentHandler2 interface ----------------------------------------
188 const RecordInfo* OoxWorkbookFragment::getRecordInfos() const
190 static const RecordInfo spRecInfos[] =
192 { OOBIN_ID_BOOKVIEWS, OOBIN_ID_BOOKVIEWS + 1 },
193 { OOBIN_ID_EXTERNALREFS, OOBIN_ID_EXTERNALREFS + 1 },
194 { OOBIN_ID_FUNCTIONGROUPS, OOBIN_ID_FUNCTIONGROUPS + 2 },
195 { OOBIN_ID_PIVOTCACHE, OOBIN_ID_PIVOTCACHE + 1 },
196 { OOBIN_ID_PIVOTCACHES, OOBIN_ID_PIVOTCACHES + 1 },
197 { OOBIN_ID_SHEETS, OOBIN_ID_SHEETS + 1 },
198 { OOBIN_ID_WORKBOOK, OOBIN_ID_WORKBOOK + 1 },
199 { -1, -1 }
201 return spRecInfos;
204 void OoxWorkbookFragment::finalizeImport()
206 ISegmentProgressBarRef xGlobalSegment = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
208 // read the theme substream
209 OUString aThemeFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATIONSTYPE( "theme" ) );
210 if( aThemeFragmentPath.getLength() > 0 )
211 importOoxFragment( new ThemeFragmentHandler( getFilter(), aThemeFragmentPath, getTheme() ) );
212 xGlobalSegment->setPosition( 0.25 );
214 // read the styles substream (requires finalized theme buffer)
215 OUString aStylesFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATIONSTYPE( "styles" ) );
216 if( aStylesFragmentPath.getLength() > 0 )
217 importOoxFragment( new OoxStylesFragment( *this, aStylesFragmentPath ) );
218 xGlobalSegment->setPosition( 0.5 );
220 // read the shared string table substream (requires finalized styles buffer)
221 OUString aSstFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATIONSTYPE( "sharedStrings" ) );
222 if( aSstFragmentPath.getLength() > 0 )
223 importOoxFragment( new OoxSharedStringsFragment( *this, aSstFragmentPath ) );
224 xGlobalSegment->setPosition( 0.75 );
226 // read the connections substream
227 OUString aConnFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATIONSTYPE( "connections" ) );
228 if( aConnFragmentPath.getLength() > 0 )
229 importOoxFragment( new OoxConnectionsFragment( *this, aConnFragmentPath ) );
230 xGlobalSegment->setPosition( 1.0 );
232 /* Create fragments for all sheets, before importing them. Needed to do
233 some preprocessing in the fragment constructors, e.g. loading the table
234 fragments for all sheets that are needed before the cell formulas are
235 loaded. */
236 typedef ::std::vector< FragmentHandlerRef > SheetFragmentVector;
237 SheetFragmentVector aSheetFragments;
238 WorksheetBuffer& rWorksheets = getWorksheets();
239 sal_Int32 nWorksheetCount = rWorksheets.getWorksheetCount();
240 for( sal_Int32 nWorksheet = 0; nWorksheet < nWorksheetCount; ++nWorksheet )
242 sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet );
243 const Relation* pRelation = getRelations().getRelationFromRelId( rWorksheets.getWorksheetRelId( nWorksheet ) );
244 if( (nCalcSheet >= 0) && pRelation )
246 // get fragment path of the sheet
247 OUString aFragmentPath = getFragmentPathFromRelation( *pRelation );
248 OSL_ENSURE( aFragmentPath.getLength() > 0, "OoxWorkbookFragment::finalizeImport - cannot access sheet fragment" );
249 if( aFragmentPath.getLength() > 0 )
251 ::rtl::Reference< OoxWorksheetFragmentBase > xFragment;
252 double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet);
253 ISegmentProgressBarRef xSheetSegment = getProgressBar().createSegment( fSegmentLength );
255 // create the fragment according to the sheet type
256 if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "worksheet" ) )
258 xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_WORKSHEET, nCalcSheet ) );
260 else if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "chartsheet" ) )
262 xFragment.set( new OoxChartsheetFragment( *this, aFragmentPath, xSheetSegment, nCalcSheet ) );
264 else if( (pRelation->maType == CREATE_MSOFFICE_RELATIONSTYPE( "xlMacrosheet" )) ||
265 (pRelation->maType == CREATE_MSOFFICE_RELATIONSTYPE( "xlIntlMacrosheet" )) )
267 xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_MACROSHEET, nCalcSheet ) );
269 else if( pRelation->maType == CREATE_OFFICEDOC_RELATIONSTYPE( "dialogsheet" ) )
271 xFragment.set( new OoxWorksheetFragment( *this, aFragmentPath, xSheetSegment, SHEETTYPE_DIALOGSHEET, nCalcSheet ) );
274 // insert the fragment into the map
275 OSL_ENSURE( xFragment.is(), "OoxWorkbookFragment::finalizeImport - unknown sheet type" );
276 OSL_ENSURE( !xFragment.is() || xFragment->isValidSheet(), "OoxWorkbookFragment::finalizeImport - missing sheet in document" );
277 if( xFragment.is() && xFragment->isValidSheet() )
278 aSheetFragments.push_back( xFragment.get() );
283 // create all defined names and database ranges
284 getDefinedNames().finalizeImport();
285 getTables().finalizeImport();
287 // load all worksheets
288 for( SheetFragmentVector::iterator aIt = aSheetFragments.begin(), aEnd = aSheetFragments.end(); aIt != aEnd; ++aIt )
290 OOX_LOADSAVE_TIMER( IMPORTSHEETFRAGMENT );
291 // import the sheet fragment
292 importOoxFragment( *aIt );
293 // delete fragment object, will free all allocated sheet buffers
294 aIt->clear();
297 // final conversions, e.g. calculation settings and view settings
298 finalizeWorkbookImport();
301 // private --------------------------------------------------------------------
303 void OoxWorkbookFragment::importExternalReference( const AttributeList& rAttribs )
305 if( ExternalLink* pExtLink = getExternalLinks().importExternalReference( rAttribs ).get() )
306 importExternalLinkFragment( *pExtLink );
309 void OoxWorkbookFragment::importDefinedName( const AttributeList& rAttribs )
311 mxCurrName = getDefinedNames().importDefinedName( rAttribs );
314 void OoxWorkbookFragment::importPivotCache( const AttributeList& rAttribs )
316 sal_Int32 nCacheId = rAttribs.getInteger( XML_cacheId, -1 );
317 OUString aRelId = rAttribs.getString( R_TOKEN( id ), OUString() );
318 importPivotCacheDefFragment( aRelId, nCacheId );
321 void OoxWorkbookFragment::importExternalRef( RecordInputStream& rStrm )
323 if( ExternalLink* pExtLink = getExternalLinks().importExternalRef( rStrm ).get() )
324 importExternalLinkFragment( *pExtLink );
327 void OoxWorkbookFragment::importPivotCache( RecordInputStream& rStrm )
329 sal_Int32 nCacheId = rStrm.readInt32();
330 OUString aRelId = rStrm.readString();
331 importPivotCacheDefFragment( aRelId, nCacheId );
334 void OoxWorkbookFragment::importExternalLinkFragment( ExternalLink& rExtLink )
336 OUString aFragmentPath = getFragmentPathFromRelId( rExtLink.getRelId() );
337 if( aFragmentPath.getLength() > 0 )
338 importOoxFragment( new OoxExternalLinkFragment( *this, aFragmentPath, rExtLink ) );
341 void OoxWorkbookFragment::importPivotCacheDefFragment( const OUString& rRelId, sal_Int32 nCacheId )
343 // pivot caches will be imported on demand, here we just store the fragment path in the buffer
344 getPivotCaches().registerPivotCacheFragment( nCacheId, getFragmentPathFromRelId( rRelId ) );
347 // ============================================================================
349 BiffWorkbookFragment::BiffWorkbookFragment( const WorkbookHelper& rHelper, const OUString& rStrmName ) :
350 BiffWorkbookFragmentBase( rHelper, rStrmName )
354 bool BiffWorkbookFragment::importFragment()
356 bool bRet = false;
358 BiffFragmentType eFragment = startFragment( getBiff() );
359 switch( eFragment )
361 case BIFF_FRAGMENT_GLOBALS:
363 // import workbook globals fragment and create sheets in document
364 ISegmentProgressBarRef xGlobalsProgress = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
365 bRet = importGlobalsFragment( *xGlobalsProgress );
366 // load sheet fragments (do not return false in bRet on missing/broken sheets)
367 WorksheetBuffer& rWorksheets = getWorksheets();
368 bool bNextSheet = bRet;
369 for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet )
371 // try to start a new sheet fragment
372 double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet);
373 ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength );
374 BiffFragmentType eSheetFragment = startFragment( getBiff(), rWorksheets.getBiffRecordHandle( nWorksheet ) );
375 sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet );
376 bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCalcSheet );
379 break;
381 case BIFF_FRAGMENT_WORKSPACE:
383 bRet = importWorkspaceFragment();
384 // sheets are embedded in workspace fragment, nothing to do here
386 break;
388 case BIFF_FRAGMENT_WORKSHEET:
389 case BIFF_FRAGMENT_CHARTSHEET:
390 case BIFF_FRAGMENT_MACROSHEET:
392 /* Single sheet without globals
393 - #i62752# possible in all BIFF versions
394 - do not return false in bRet on missing/broken sheets. */
395 getWorksheets().initializeSingleSheet();
396 importSheetFragment( getProgressBar(), eFragment, 0 );
397 // success, even if stream is broken
398 bRet = true;
400 break;
402 default:;
405 // final conversions, e.g. calculation settings and view settings
406 if( bRet )
407 finalizeWorkbookImport();
409 return bRet;
412 bool BiffWorkbookFragment::importWorkspaceFragment()
414 // enable workbook mode, has not been set yet in BIFF4 workspace files
415 setIsWorkbookFile();
417 WorksheetBuffer& rWorksheets = getWorksheets();
418 bool bRet = true;
420 // import the workspace globals
421 ISegmentProgressBarRef xGlobalsProgress = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS );
422 bool bLoop = true;
423 while( bRet && bLoop && mrStrm.startNextRecord() && (mrStrm.getRecId() != BIFF_ID_EOF) )
425 switch( mrStrm.getRecId() )
427 case BIFF_ID_SHEET: rWorksheets.importSheet( mrStrm ); break;
428 case BIFF_ID_CODEPAGE: setCodePage( mrStrm.readuInt16() ); break;
429 case BIFF_ID_FILEPASS: bRet = getCodecHelper().importFilePass( mrStrm ); break;
430 case BIFF_ID_SHEETHEADER: mrStrm.rewindRecord(); bLoop = false; break;
433 xGlobalsProgress->setPosition( 1.0 );
435 // load sheet fragments (do not return false in bRet on missing/broken sheets)
436 bool bNextSheet = bRet;
437 for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet )
439 // try to start a new sheet fragment (with leading SHEETHEADER record)
440 bNextSheet = mrStrm.startNextRecord() && (mrStrm.getRecId() == BIFF_ID_SHEETHEADER);
441 if( bNextSheet )
443 double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet);
444 ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength );
445 /* Read current sheet name (sheet substreams may not be in the
446 same order as SHEET records are). */
447 mrStrm.skip( 4 );
448 OUString aSheetName = mrStrm.readByteStringUC( false, getTextEncoding() );
449 sal_Int16 nCurrSheet = rWorksheets.getCalcSheetIndex( aSheetName );
450 // load the sheet fragment records
451 BiffFragmentType eSheetFragment = startFragment( getBiff() );
452 bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCurrSheet );
453 // do not return false in bRet on missing/broken sheets
457 return bRet;
460 bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgressBar )
462 WorkbookSettings& rWorkbookSett = getWorkbookSettings();
463 ViewSettings& rViewSett = getViewSettings();
464 SharedStringsBuffer& rSharedStrings = getSharedStrings();
465 StylesBuffer& rStyles = getStyles();
466 WorksheetBuffer& rWorksheets = getWorksheets();
467 PivotCacheBuffer& rPivotCaches = getPivotCaches();
469 // collect records that need to be loaded in a second pass
470 typedef ::std::vector< sal_Int64 > RecordHandleVec;
471 RecordHandleVec aExtLinkRecs;
473 bool bRet = true;
474 bool bLoop = true;
475 while( bRet && bLoop && mrStrm.startNextRecord() )
477 sal_uInt16 nRecId = mrStrm.getRecId();
478 bool bExtLinkRec = false;
480 /* #i56376# BIFF5-BIFF8: If an EOF record for globals is missing,
481 simulate it. The issue is about a document where the sheet fragment
482 starts directly after the EXTSST record, without terminating the
483 globals fragment with an EOF record. */
484 if( isBofRecord() || (nRecId == BIFF_ID_EOF) )
486 bLoop = false;
488 else switch( nRecId )
490 // records in all BIFF versions
491 case BIFF_ID_CODEPAGE: setCodePage( mrStrm.readuInt16() ); break;
492 case BIFF_ID_DATEMODE: rWorkbookSett.importDateMode( mrStrm ); break;
493 case BIFF_ID_FILEPASS: bRet = getCodecHelper().importFilePass( mrStrm ); break;
494 case BIFF_ID_PRECISION: rWorkbookSett.importPrecision( mrStrm ); break;
495 case BIFF_ID_WINDOW1: rViewSett.importWindow1( mrStrm ); break;
497 // BIFF specific records
498 default: switch( getBiff() )
500 case BIFF2: switch( nRecId )
502 case BIFF2_ID_DEFINEDNAME: bExtLinkRec = true; break;
503 case BIFF2_ID_EXTERNALNAME: bExtLinkRec = true; break;
504 case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
505 case BIFF2_ID_FONT: rStyles.importFont( mrStrm ); break;
506 case BIFF_ID_FONTCOLOR: rStyles.importFontColor( mrStrm ); break;
507 case BIFF2_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
508 case BIFF2_ID_XF: rStyles.importXf( mrStrm ); break;
510 break;
512 case BIFF3: switch( nRecId )
514 case BIFF_ID_CRN: bExtLinkRec = true; break;
515 case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break;
516 case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break;
517 case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
518 case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( mrStrm ); break;
519 case BIFF3_ID_FONT: rStyles.importFont( mrStrm ); break;
520 case BIFF2_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
521 case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break;
522 case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break;
523 case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break;
524 case BIFF_ID_XCT: bExtLinkRec = true; break;
525 case BIFF3_ID_XF: rStyles.importXf( mrStrm ); break;
527 break;
529 case BIFF4: switch( nRecId )
531 case BIFF_ID_CRN: bExtLinkRec = true; break;
532 case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break;
533 case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break;
534 case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
535 case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( mrStrm ); break;
536 case BIFF3_ID_FONT: rStyles.importFont( mrStrm ); break;
537 case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
538 case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break;
539 case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break;
540 case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break;
541 case BIFF_ID_XCT: bExtLinkRec = true; break;
542 case BIFF4_ID_XF: rStyles.importXf( mrStrm ); break;
544 break;
546 case BIFF5: switch( nRecId )
548 case BIFF_ID_BOOKBOOL: rWorkbookSett.importBookBool( mrStrm ); break;
549 case BIFF_ID_CRN: bExtLinkRec = true; break;
550 case BIFF5_ID_DEFINEDNAME: bExtLinkRec = true; break;
551 case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break;
552 case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
553 case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( mrStrm ); break;
554 case BIFF5_ID_FONT: rStyles.importFont( mrStrm ); break;
555 case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
556 case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break;
557 case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break;
558 case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( mrStrm ); break;
559 case BIFF_ID_SHEET: rWorksheets.importSheet( mrStrm ); break;
560 case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break;
561 case BIFF_ID_XCT: bExtLinkRec = true; break;
562 case BIFF5_ID_XF: rStyles.importXf( mrStrm ); break;
564 break;
566 case BIFF8: switch( nRecId )
568 case BIFF_ID_BOOKBOOL: rWorkbookSett.importBookBool( mrStrm ); break;
569 case BIFF_ID_CODENAME: rWorkbookSett.importCodeName( mrStrm ); break;
570 case BIFF_ID_CRN: bExtLinkRec = true; break;
571 case BIFF5_ID_DEFINEDNAME: bExtLinkRec = true; break;
572 case BIFF_ID_EXTERNALBOOK: bExtLinkRec = true; break;
573 case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break;
574 case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break;
575 case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( mrStrm ); break;
576 case BIFF5_ID_FONT: rStyles.importFont( mrStrm ); break;
577 case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break;
578 case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break;
579 case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break;
580 case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( mrStrm ); break;
581 case BIFF_ID_SHEET: rWorksheets.importSheet( mrStrm ); break;
582 case BIFF_ID_SST: rSharedStrings.importSst( mrStrm ); break;
583 case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break;
584 case BIFF_ID_USESELFS: rWorkbookSett.importUsesElfs( mrStrm ); break;
585 case BIFF_ID_XCT: bExtLinkRec = true; break;
586 case BIFF5_ID_XF: rStyles.importXf( mrStrm ); break;
588 break;
590 case BIFF_UNKNOWN: break;
594 if( bExtLinkRec )
595 aExtLinkRecs.push_back( mrStrm.getRecHandle() );
598 // finalize global buffers
599 rProgressBar.setPosition( 0.5 );
600 if( bRet )
602 rSharedStrings.finalizeImport();
603 rStyles.finalizeImport();
606 /* Import external link data (EXTERNSHEET, EXTERNALNAME, DEFINEDNAME)
607 which need existing internal sheets (SHEET records). The SHEET records
608 may follow the external links records in some BIFF versions. */
609 if( bRet && !aExtLinkRecs.empty() )
611 // remember current stream position (the EOF record)
612 sal_Int64 nEofHandle = mrStrm.getRecHandle();
613 // this fragment class implements import of external link records
614 BiffExternalLinkFragment aLinkFragment( *this, true );
615 // import all records by using their cached record handle
616 for( RecordHandleVec::const_iterator aIt = aExtLinkRecs.begin(), aEnd = aExtLinkRecs.end(); (aIt != aEnd) && mrStrm.startRecordByHandle( *aIt ); ++aIt )
617 aLinkFragment.importRecord();
618 // finalize global buffers
619 aLinkFragment.finalizeImport();
620 // seek back to the EOF record of the workbook globals fragment
621 bRet = mrStrm.startRecordByHandle( nEofHandle );
624 // #i56376# missing EOF - rewind before worksheet BOF record (see above)
625 if( bRet && isBofRecord() )
626 mrStrm.rewindRecord();
628 rProgressBar.setPosition( 1.0 );
629 return bRet;
632 bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBar, BiffFragmentType eFragment, sal_Int16 nCalcSheet )
634 // no Calc sheet - skip the fragment
635 if( nCalcSheet < 0 )
636 return skipFragment();
638 // find the sheet type for this fragment
639 WorksheetType eSheetType = SHEETTYPE_EMPTYSHEET;
640 switch( eFragment )
642 case BIFF_FRAGMENT_WORKSHEET: eSheetType = SHEETTYPE_WORKSHEET; break;
643 case BIFF_FRAGMENT_CHARTSHEET: eSheetType = SHEETTYPE_CHARTSHEET; break;
644 case BIFF_FRAGMENT_MACROSHEET: eSheetType = SHEETTYPE_MACROSHEET; break;
645 case BIFF_FRAGMENT_MODULESHEET: eSheetType = SHEETTYPE_MODULESHEET; break;
646 case BIFF_FRAGMENT_EMPTYSHEET: eSheetType = SHEETTYPE_EMPTYSHEET; break;
647 default: return false;
650 /* #i11183# Clear buffers that are used per-sheet, e.g. external links in
651 BIFF4W and BIFF5 files, or defined names in BIFF4W files. */
652 createBuffersPerSheet( nCalcSheet );
654 // preprocess some records
655 switch( getBiff() )
657 // load the workbook globals fragment records in BIFF2-BIFF4
658 case BIFF2:
659 case BIFF3:
660 case BIFF4:
662 // remember current record to seek back below
663 sal_Int64 nRecHandle = mrStrm.getRecHandle();
664 // import the global records
665 ISegmentProgressBarRef xGlobalsProgress = rProgressBar.createSegment( PROGRESS_LENGTH_GLOBALS );
666 importGlobalsFragment( *xGlobalsProgress );
667 // rewind stream to fragment BOF record
668 mrStrm.startRecordByHandle( nRecHandle );
670 break;
672 // load the external link records for this sheet in BIFF5
673 case BIFF5:
675 // remember current record to seek back below
676 sal_Int64 nRecHandle = mrStrm.getRecHandle();
677 // fragment implementing import of external link records
678 BiffExternalLinkFragment( *this, false ).importFragment();
679 // rewind stream to fragment BOF record
680 mrStrm.startRecordByHandle( nRecHandle );
682 break;
684 case BIFF8:
685 break;
687 case BIFF_UNKNOWN:
688 break;
691 // create the worksheet fragment
692 ISegmentProgressBarRef xSheetProgress = rProgressBar.createSegment( rProgressBar.getFreeLength() );
693 ::boost::shared_ptr< BiffWorksheetFragmentBase > xFragment;
694 switch( eSheetType )
696 case SHEETTYPE_WORKSHEET:
697 case SHEETTYPE_MACROSHEET:
698 case SHEETTYPE_DIALOGSHEET:
699 xFragment.reset( new BiffWorksheetFragment( *this, xSheetProgress, eSheetType, nCalcSheet ) );
700 break;
701 case SHEETTYPE_CHARTSHEET:
702 xFragment.reset( new BiffChartsheetFragment( *this, xSheetProgress, nCalcSheet ) );
703 break;
704 case SHEETTYPE_MODULESHEET:
705 case SHEETTYPE_EMPTYSHEET:
706 xFragment.reset( new BiffSkipWorksheetFragment( *this, xSheetProgress, nCalcSheet ) );
707 break;
709 // load the sheet fragment records
710 return xFragment->isValidSheet() && xFragment->importFragment();
713 // ============================================================================
715 } // namespace xls
716 } // namespace oox