1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "oox/xls/workbookfragment.hxx" 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #include <com/sun/star/table/CellAddress.hpp> 31*cdf0e10cSrcweir #include "oox/core/filterbase.hxx" 32*cdf0e10cSrcweir #include "oox/drawingml/themefragmenthandler.hxx" 33*cdf0e10cSrcweir #include "oox/helper/attributelist.hxx" 34*cdf0e10cSrcweir #include "oox/helper/progressbar.hxx" 35*cdf0e10cSrcweir #include "oox/helper/propertyset.hxx" 36*cdf0e10cSrcweir #include "oox/ole/olestorage.hxx" 37*cdf0e10cSrcweir #include "oox/xls/biffinputstream.hxx" 38*cdf0e10cSrcweir #include "oox/xls/chartsheetfragment.hxx" 39*cdf0e10cSrcweir #include "oox/xls/connectionsfragment.hxx" 40*cdf0e10cSrcweir #include "oox/xls/externallinkbuffer.hxx" 41*cdf0e10cSrcweir #include "oox/xls/externallinkfragment.hxx" 42*cdf0e10cSrcweir #include "oox/xls/pivotcachebuffer.hxx" 43*cdf0e10cSrcweir #include "oox/xls/sharedstringsbuffer.hxx" 44*cdf0e10cSrcweir #include "oox/xls/sharedstringsfragment.hxx" 45*cdf0e10cSrcweir #include "oox/xls/stylesfragment.hxx" 46*cdf0e10cSrcweir #include "oox/xls/tablebuffer.hxx" 47*cdf0e10cSrcweir #include "oox/xls/themebuffer.hxx" 48*cdf0e10cSrcweir #include "oox/xls/viewsettings.hxx" 49*cdf0e10cSrcweir #include "oox/xls/workbooksettings.hxx" 50*cdf0e10cSrcweir #include "oox/xls/worksheetbuffer.hxx" 51*cdf0e10cSrcweir #include "oox/xls/worksheetfragment.hxx" 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir namespace oox { 54*cdf0e10cSrcweir namespace xls { 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir // ============================================================================ 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir using namespace ::com::sun::star::io; 59*cdf0e10cSrcweir using namespace ::com::sun::star::table; 60*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 61*cdf0e10cSrcweir using namespace ::oox::core; 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir using ::oox::drawingml::ThemeFragmentHandler; 64*cdf0e10cSrcweir using ::rtl::OUString; 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir // ============================================================================ 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir namespace { 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir const double PROGRESS_LENGTH_GLOBALS = 0.1; /// 10% of progress bar for globals import. 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir } // namespace 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir // ============================================================================ 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir WorkbookFragment::WorkbookFragment( const WorkbookHelper& rHelper, const OUString& rFragmentPath ) : 77*cdf0e10cSrcweir WorkbookFragmentBase( rHelper, rFragmentPath ) 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir } 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir ContextHandlerRef WorkbookFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir switch( getCurrentElement() ) 84*cdf0e10cSrcweir { 85*cdf0e10cSrcweir case XML_ROOT_CONTEXT: 86*cdf0e10cSrcweir if( nElement == XLS_TOKEN( workbook ) ) return this; 87*cdf0e10cSrcweir break; 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir case XLS_TOKEN( workbook ): 90*cdf0e10cSrcweir switch( nElement ) 91*cdf0e10cSrcweir { 92*cdf0e10cSrcweir case XLS_TOKEN( sheets ): 93*cdf0e10cSrcweir case XLS_TOKEN( bookViews ): 94*cdf0e10cSrcweir case XLS_TOKEN( externalReferences ): 95*cdf0e10cSrcweir case XLS_TOKEN( definedNames ): 96*cdf0e10cSrcweir case XLS_TOKEN( pivotCaches ): return this; 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir case XLS_TOKEN( fileSharing ): getWorkbookSettings().importFileSharing( rAttribs ); break; 99*cdf0e10cSrcweir case XLS_TOKEN( workbookPr ): getWorkbookSettings().importWorkbookPr( rAttribs ); break; 100*cdf0e10cSrcweir case XLS_TOKEN( calcPr ): getWorkbookSettings().importCalcPr( rAttribs ); break; 101*cdf0e10cSrcweir case XLS_TOKEN( oleSize ): getViewSettings().importOleSize( rAttribs ); break; 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir break; 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir case XLS_TOKEN( sheets ): 106*cdf0e10cSrcweir if( nElement == XLS_TOKEN( sheet ) ) getWorksheets().importSheet( rAttribs ); 107*cdf0e10cSrcweir break; 108*cdf0e10cSrcweir case XLS_TOKEN( bookViews ): 109*cdf0e10cSrcweir if( nElement == XLS_TOKEN( workbookView ) ) getViewSettings().importWorkbookView( rAttribs ); 110*cdf0e10cSrcweir break; 111*cdf0e10cSrcweir case XLS_TOKEN( externalReferences ): 112*cdf0e10cSrcweir if( nElement == XLS_TOKEN( externalReference ) ) importExternalReference( rAttribs ); 113*cdf0e10cSrcweir break; 114*cdf0e10cSrcweir case XLS_TOKEN( definedNames ): 115*cdf0e10cSrcweir if( nElement == XLS_TOKEN( definedName ) ) { importDefinedName( rAttribs ); return this; } // collect formula 116*cdf0e10cSrcweir break; 117*cdf0e10cSrcweir case XLS_TOKEN( pivotCaches ): 118*cdf0e10cSrcweir if( nElement == XLS_TOKEN( pivotCache ) ) importPivotCache( rAttribs ); 119*cdf0e10cSrcweir break; 120*cdf0e10cSrcweir } 121*cdf0e10cSrcweir return 0; 122*cdf0e10cSrcweir } 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir void WorkbookFragment::onCharacters( const OUString& rChars ) 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir if( isCurrentElement( XLS_TOKEN( definedName ) ) && mxCurrName.get() ) 127*cdf0e10cSrcweir mxCurrName->setFormula( rChars ); 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir ContextHandlerRef WorkbookFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir switch( getCurrentElement() ) 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir case XML_ROOT_CONTEXT: 135*cdf0e10cSrcweir if( nRecId == BIFF12_ID_WORKBOOK ) return this; 136*cdf0e10cSrcweir break; 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir case BIFF12_ID_WORKBOOK: 139*cdf0e10cSrcweir switch( nRecId ) 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir case BIFF12_ID_SHEETS: 142*cdf0e10cSrcweir case BIFF12_ID_BOOKVIEWS: 143*cdf0e10cSrcweir case BIFF12_ID_EXTERNALREFS: 144*cdf0e10cSrcweir case BIFF12_ID_PIVOTCACHES: return this; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir case BIFF12_ID_FILESHARING: getWorkbookSettings().importFileSharing( rStrm ); break; 147*cdf0e10cSrcweir case BIFF12_ID_WORKBOOKPR: getWorkbookSettings().importWorkbookPr( rStrm ); break; 148*cdf0e10cSrcweir case BIFF12_ID_CALCPR: getWorkbookSettings().importCalcPr( rStrm ); break; 149*cdf0e10cSrcweir case BIFF12_ID_OLESIZE: getViewSettings().importOleSize( rStrm ); break; 150*cdf0e10cSrcweir case BIFF12_ID_DEFINEDNAME: getDefinedNames().importDefinedName( rStrm ); break; 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir break; 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir case BIFF12_ID_SHEETS: 155*cdf0e10cSrcweir if( nRecId == BIFF12_ID_SHEET ) getWorksheets().importSheet( rStrm ); 156*cdf0e10cSrcweir break; 157*cdf0e10cSrcweir case BIFF12_ID_BOOKVIEWS: 158*cdf0e10cSrcweir if( nRecId == BIFF12_ID_WORKBOOKVIEW ) getViewSettings().importWorkbookView( rStrm ); 159*cdf0e10cSrcweir break; 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir case BIFF12_ID_EXTERNALREFS: 162*cdf0e10cSrcweir switch( nRecId ) 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir case BIFF12_ID_EXTERNALREF: importExternalRef( rStrm ); break; 165*cdf0e10cSrcweir case BIFF12_ID_EXTERNALSELF: getExternalLinks().importExternalSelf( rStrm ); break; 166*cdf0e10cSrcweir case BIFF12_ID_EXTERNALSAME: getExternalLinks().importExternalSame( rStrm ); break; 167*cdf0e10cSrcweir case BIFF12_ID_EXTERNALADDIN: getExternalLinks().importExternalAddin( rStrm ); break; 168*cdf0e10cSrcweir case BIFF12_ID_EXTERNALSHEETS: getExternalLinks().importExternalSheets( rStrm ); break; 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir break; 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir case BIFF12_ID_PIVOTCACHES: 173*cdf0e10cSrcweir if( nRecId == BIFF12_ID_PIVOTCACHE ) importPivotCache( rStrm ); 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir return 0; 176*cdf0e10cSrcweir } 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir const RecordInfo* WorkbookFragment::getRecordInfos() const 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir static const RecordInfo spRecInfos[] = 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir { BIFF12_ID_BOOKVIEWS, BIFF12_ID_BOOKVIEWS + 1 }, 183*cdf0e10cSrcweir { BIFF12_ID_EXTERNALREFS, BIFF12_ID_EXTERNALREFS + 1 }, 184*cdf0e10cSrcweir { BIFF12_ID_FUNCTIONGROUPS, BIFF12_ID_FUNCTIONGROUPS + 2 }, 185*cdf0e10cSrcweir { BIFF12_ID_PIVOTCACHE, BIFF12_ID_PIVOTCACHE + 1 }, 186*cdf0e10cSrcweir { BIFF12_ID_PIVOTCACHES, BIFF12_ID_PIVOTCACHES + 1 }, 187*cdf0e10cSrcweir { BIFF12_ID_SHEETS, BIFF12_ID_SHEETS + 1 }, 188*cdf0e10cSrcweir { BIFF12_ID_WORKBOOK, BIFF12_ID_WORKBOOK + 1 }, 189*cdf0e10cSrcweir { -1, -1 } 190*cdf0e10cSrcweir }; 191*cdf0e10cSrcweir return spRecInfos; 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir void WorkbookFragment::finalizeImport() 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir ISegmentProgressBarRef xGlobalSegment = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS ); 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir // read the theme substream 199*cdf0e10cSrcweir OUString aThemeFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "theme" ) ); 200*cdf0e10cSrcweir if( aThemeFragmentPath.getLength() > 0 ) 201*cdf0e10cSrcweir importOoxFragment( new ThemeFragmentHandler( getFilter(), aThemeFragmentPath, getTheme() ) ); 202*cdf0e10cSrcweir xGlobalSegment->setPosition( 0.25 ); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir // read the styles substream (requires finalized theme buffer) 205*cdf0e10cSrcweir OUString aStylesFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "styles" ) ); 206*cdf0e10cSrcweir if( aStylesFragmentPath.getLength() > 0 ) 207*cdf0e10cSrcweir importOoxFragment( new StylesFragment( *this, aStylesFragmentPath ) ); 208*cdf0e10cSrcweir xGlobalSegment->setPosition( 0.5 ); 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir // read the shared string table substream (requires finalized styles buffer) 211*cdf0e10cSrcweir OUString aSstFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "sharedStrings" ) ); 212*cdf0e10cSrcweir if( aSstFragmentPath.getLength() > 0 ) 213*cdf0e10cSrcweir importOoxFragment( new SharedStringsFragment( *this, aSstFragmentPath ) ); 214*cdf0e10cSrcweir xGlobalSegment->setPosition( 0.75 ); 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir // read the connections substream 217*cdf0e10cSrcweir OUString aConnFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "connections" ) ); 218*cdf0e10cSrcweir if( aConnFragmentPath.getLength() > 0 ) 219*cdf0e10cSrcweir importOoxFragment( new ConnectionsFragment( *this, aConnFragmentPath ) ); 220*cdf0e10cSrcweir xGlobalSegment->setPosition( 1.0 ); 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir /* Create fragments for all sheets, before importing them. Needed to do 223*cdf0e10cSrcweir some preprocessing in the fragment constructors, e.g. loading the table 224*cdf0e10cSrcweir fragments for all sheets that are needed before the cell formulas are 225*cdf0e10cSrcweir loaded. Additionally, the instances of the WorkbookGlobals structures 226*cdf0e10cSrcweir have to be stored for every sheet. */ 227*cdf0e10cSrcweir typedef ::std::pair< WorksheetGlobalsRef, FragmentHandlerRef > SheetFragmentHandler; 228*cdf0e10cSrcweir typedef ::std::vector< SheetFragmentHandler > SheetFragmentVector; 229*cdf0e10cSrcweir SheetFragmentVector aSheetFragments; 230*cdf0e10cSrcweir WorksheetBuffer& rWorksheets = getWorksheets(); 231*cdf0e10cSrcweir sal_Int32 nWorksheetCount = rWorksheets.getWorksheetCount(); 232*cdf0e10cSrcweir for( sal_Int32 nWorksheet = 0; nWorksheet < nWorksheetCount; ++nWorksheet ) 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet ); 235*cdf0e10cSrcweir const Relation* pRelation = getRelations().getRelationFromRelId( rWorksheets.getWorksheetRelId( nWorksheet ) ); 236*cdf0e10cSrcweir if( (nCalcSheet >= 0) && pRelation ) 237*cdf0e10cSrcweir { 238*cdf0e10cSrcweir // get fragment path of the sheet 239*cdf0e10cSrcweir OUString aFragmentPath = getFragmentPathFromRelation( *pRelation ); 240*cdf0e10cSrcweir OSL_ENSURE( aFragmentPath.getLength() > 0, "WorkbookFragment::finalizeImport - cannot access sheet fragment" ); 241*cdf0e10cSrcweir if( aFragmentPath.getLength() > 0 ) 242*cdf0e10cSrcweir { 243*cdf0e10cSrcweir double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); 244*cdf0e10cSrcweir ISegmentProgressBarRef xSheetSegment = getProgressBar().createSegment( fSegmentLength ); 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir // get the sheet type according to the relations type 247*cdf0e10cSrcweir WorksheetType eSheetType = SHEETTYPE_EMPTYSHEET; 248*cdf0e10cSrcweir if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "worksheet" ) ) 249*cdf0e10cSrcweir eSheetType = SHEETTYPE_WORKSHEET; 250*cdf0e10cSrcweir else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "chartsheet" ) ) 251*cdf0e10cSrcweir eSheetType = SHEETTYPE_CHARTSHEET; 252*cdf0e10cSrcweir else if( (pRelation->maType == CREATE_MSOFFICE_RELATION_TYPE( "xlMacrosheet" )) || 253*cdf0e10cSrcweir (pRelation->maType == CREATE_MSOFFICE_RELATION_TYPE( "xlIntlMacrosheet" )) ) 254*cdf0e10cSrcweir eSheetType = SHEETTYPE_MACROSHEET; 255*cdf0e10cSrcweir else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "dialogsheet" ) ) 256*cdf0e10cSrcweir eSheetType = SHEETTYPE_DIALOGSHEET; 257*cdf0e10cSrcweir OSL_ENSURE( eSheetType != SHEETTYPE_EMPTYSHEET, "WorkbookFragment::finalizeImport - unknown sheet type" ); 258*cdf0e10cSrcweir if( eSheetType != SHEETTYPE_EMPTYSHEET ) 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir // create the WorksheetGlobals object 261*cdf0e10cSrcweir WorksheetGlobalsRef xSheetGlob = WorksheetHelper::constructGlobals( *this, xSheetSegment, eSheetType, nCalcSheet ); 262*cdf0e10cSrcweir OSL_ENSURE( xSheetGlob.get(), "WorkbookFragment::finalizeImport - missing sheet in document" ); 263*cdf0e10cSrcweir if( xSheetGlob.get() ) 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir // create the sheet fragment handler 266*cdf0e10cSrcweir ::rtl::Reference< WorksheetFragmentBase > xFragment; 267*cdf0e10cSrcweir switch( eSheetType ) 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir case SHEETTYPE_WORKSHEET: 270*cdf0e10cSrcweir case SHEETTYPE_MACROSHEET: 271*cdf0e10cSrcweir case SHEETTYPE_DIALOGSHEET: 272*cdf0e10cSrcweir xFragment.set( new WorksheetFragment( *xSheetGlob, aFragmentPath ) ); 273*cdf0e10cSrcweir break; 274*cdf0e10cSrcweir case SHEETTYPE_CHARTSHEET: 275*cdf0e10cSrcweir xFragment.set( new ChartsheetFragment( *xSheetGlob, aFragmentPath ) ); 276*cdf0e10cSrcweir break; 277*cdf0e10cSrcweir default: 278*cdf0e10cSrcweir OSL_ENSURE( false, "WorkbookFragment::finalizeImport - unexpected sheet type" ); 279*cdf0e10cSrcweir } 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir // insert the fragment into the map 282*cdf0e10cSrcweir if( xFragment.is() ) 283*cdf0e10cSrcweir aSheetFragments.push_back( SheetFragmentHandler( xSheetGlob, xFragment.get() ) ); 284*cdf0e10cSrcweir } 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir // create all defined names and database ranges 291*cdf0e10cSrcweir getDefinedNames().finalizeImport(); 292*cdf0e10cSrcweir getTables().finalizeImport(); 293*cdf0e10cSrcweir 294*cdf0e10cSrcweir // load all worksheets 295*cdf0e10cSrcweir for( SheetFragmentVector::iterator aIt = aSheetFragments.begin(), aEnd = aSheetFragments.end(); aIt != aEnd; ++aIt ) 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir // import the sheet fragment 298*cdf0e10cSrcweir importOoxFragment( aIt->second ); 299*cdf0e10cSrcweir // delete fragment object and WorkbookGlobals object, will free all allocated sheet buffers 300*cdf0e10cSrcweir aIt->second.clear(); 301*cdf0e10cSrcweir aIt->first.reset(); 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir // open the VBA project storage 305*cdf0e10cSrcweir OUString aVbaFragmentPath = getFragmentPathFromFirstType( CREATE_MSOFFICE_RELATION_TYPE( "vbaProject" ) ); 306*cdf0e10cSrcweir if( aVbaFragmentPath.getLength() > 0 ) 307*cdf0e10cSrcweir { 308*cdf0e10cSrcweir Reference< XInputStream > xInStrm = getBaseFilter().openInputStream( aVbaFragmentPath ); 309*cdf0e10cSrcweir if( xInStrm.is() ) 310*cdf0e10cSrcweir setVbaProjectStorage( StorageRef( new ::oox::ole::OleStorage( getBaseFilter().getComponentContext(), xInStrm, false ) ) ); 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir // final conversions, e.g. calculation settings and view settings 314*cdf0e10cSrcweir finalizeWorkbookImport(); 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir // private -------------------------------------------------------------------- 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir void WorkbookFragment::importExternalReference( const AttributeList& rAttribs ) 320*cdf0e10cSrcweir { 321*cdf0e10cSrcweir if( ExternalLink* pExtLink = getExternalLinks().importExternalReference( rAttribs ).get() ) 322*cdf0e10cSrcweir importExternalLinkFragment( *pExtLink ); 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir void WorkbookFragment::importDefinedName( const AttributeList& rAttribs ) 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir mxCurrName = getDefinedNames().importDefinedName( rAttribs ); 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir void WorkbookFragment::importPivotCache( const AttributeList& rAttribs ) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir sal_Int32 nCacheId = rAttribs.getInteger( XML_cacheId, -1 ); 333*cdf0e10cSrcweir OUString aRelId = rAttribs.getString( R_TOKEN( id ), OUString() ); 334*cdf0e10cSrcweir importPivotCacheDefFragment( aRelId, nCacheId ); 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir void WorkbookFragment::importExternalRef( SequenceInputStream& rStrm ) 338*cdf0e10cSrcweir { 339*cdf0e10cSrcweir if( ExternalLink* pExtLink = getExternalLinks().importExternalRef( rStrm ).get() ) 340*cdf0e10cSrcweir importExternalLinkFragment( *pExtLink ); 341*cdf0e10cSrcweir } 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir void WorkbookFragment::importPivotCache( SequenceInputStream& rStrm ) 344*cdf0e10cSrcweir { 345*cdf0e10cSrcweir sal_Int32 nCacheId = rStrm.readInt32(); 346*cdf0e10cSrcweir OUString aRelId = BiffHelper::readString( rStrm ); 347*cdf0e10cSrcweir importPivotCacheDefFragment( aRelId, nCacheId ); 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir void WorkbookFragment::importExternalLinkFragment( ExternalLink& rExtLink ) 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir OUString aFragmentPath = getFragmentPathFromRelId( rExtLink.getRelId() ); 353*cdf0e10cSrcweir if( aFragmentPath.getLength() > 0 ) 354*cdf0e10cSrcweir importOoxFragment( new ExternalLinkFragment( *this, aFragmentPath, rExtLink ) ); 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir 357*cdf0e10cSrcweir void WorkbookFragment::importPivotCacheDefFragment( const OUString& rRelId, sal_Int32 nCacheId ) 358*cdf0e10cSrcweir { 359*cdf0e10cSrcweir // pivot caches will be imported on demand, here we just store the fragment path in the buffer 360*cdf0e10cSrcweir getPivotCaches().registerPivotCacheFragment( nCacheId, getFragmentPathFromRelId( rRelId ) ); 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir 363*cdf0e10cSrcweir // ============================================================================ 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir BiffWorkbookFragment::BiffWorkbookFragment( const WorkbookHelper& rHelper, const OUString& rStrmName ) : 366*cdf0e10cSrcweir BiffWorkbookFragmentBase( rHelper, rStrmName ) 367*cdf0e10cSrcweir { 368*cdf0e10cSrcweir } 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir bool BiffWorkbookFragment::importFragment() 371*cdf0e10cSrcweir { 372*cdf0e10cSrcweir bool bRet = false; 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir BiffFragmentType eFragment = startFragment( getBiff() ); 375*cdf0e10cSrcweir switch( eFragment ) 376*cdf0e10cSrcweir { 377*cdf0e10cSrcweir case BIFF_FRAGMENT_GLOBALS: 378*cdf0e10cSrcweir { 379*cdf0e10cSrcweir BiffInputStream& rStrm = getInputStream(); 380*cdf0e10cSrcweir // import workbook globals fragment and create sheets in document 381*cdf0e10cSrcweir ISegmentProgressBarRef xGlobalsProgress = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS ); 382*cdf0e10cSrcweir bRet = importGlobalsFragment( *xGlobalsProgress ); 383*cdf0e10cSrcweir // load sheet fragments (do not return false in bRet on missing/broken sheets) 384*cdf0e10cSrcweir WorksheetBuffer& rWorksheets = getWorksheets(); 385*cdf0e10cSrcweir bool bNextSheet = bRet; 386*cdf0e10cSrcweir for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet ) 387*cdf0e10cSrcweir { 388*cdf0e10cSrcweir // calculate progress size for the sheet 389*cdf0e10cSrcweir double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); 390*cdf0e10cSrcweir ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength ); 391*cdf0e10cSrcweir /* Try to start a new sheet fragment. The SHEET records point to the 392*cdf0e10cSrcweir first record of the sheet fragment which is usually a BOF record. */ 393*cdf0e10cSrcweir BiffFragmentType eSheetFragment = BIFF_FRAGMENT_UNKNOWN; 394*cdf0e10cSrcweir sal_Int64 nRecHandle = rWorksheets.getBiffRecordHandle( nWorksheet ); 395*cdf0e10cSrcweir if( rStrm.startRecordByHandle( nRecHandle ) ) 396*cdf0e10cSrcweir { 397*cdf0e10cSrcweir /* #i109800# Stream may point to any record of the sheet fragment. 398*cdf0e10cSrcweir Check the record identifier before calling startFragment(). */ 399*cdf0e10cSrcweir bool bIsBofRec = BiffHelper::isBofRecord( rStrm ); 400*cdf0e10cSrcweir /* Rewind the record. If it is the BOF record, it will be read in 401*cdf0e10cSrcweir startFragment(). In every case, stream will point before the 402*cdf0e10cSrcweir first available non-BOF record. */ 403*cdf0e10cSrcweir rStrm.rewindRecord(); 404*cdf0e10cSrcweir // if the BOF record is missing, a regular worksheet will be assumed 405*cdf0e10cSrcweir eSheetFragment = bIsBofRec ? startFragment( getBiff() ) : BIFF_FRAGMENT_WORKSHEET; 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet ); 408*cdf0e10cSrcweir bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCalcSheet ); 409*cdf0e10cSrcweir } 410*cdf0e10cSrcweir } 411*cdf0e10cSrcweir break; 412*cdf0e10cSrcweir 413*cdf0e10cSrcweir case BIFF_FRAGMENT_WORKSPACE: 414*cdf0e10cSrcweir { 415*cdf0e10cSrcweir bRet = importWorkspaceFragment(); 416*cdf0e10cSrcweir // sheets are embedded in workspace fragment, nothing to do here 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir break; 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir case BIFF_FRAGMENT_WORKSHEET: 421*cdf0e10cSrcweir case BIFF_FRAGMENT_CHARTSHEET: 422*cdf0e10cSrcweir case BIFF_FRAGMENT_MACROSHEET: 423*cdf0e10cSrcweir { 424*cdf0e10cSrcweir /* Single sheet without globals 425*cdf0e10cSrcweir - #i62752# possible in all BIFF versions 426*cdf0e10cSrcweir - do not return false in bRet on missing/broken sheets. */ 427*cdf0e10cSrcweir getWorksheets().initializeSingleSheet(); 428*cdf0e10cSrcweir importSheetFragment( getProgressBar(), eFragment, 0 ); 429*cdf0e10cSrcweir // success, even if stream is broken 430*cdf0e10cSrcweir bRet = true; 431*cdf0e10cSrcweir } 432*cdf0e10cSrcweir break; 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir default:; 435*cdf0e10cSrcweir } 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir // final conversions, e.g. calculation settings and view settings 438*cdf0e10cSrcweir if( bRet ) 439*cdf0e10cSrcweir finalizeWorkbookImport(); 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir return bRet; 442*cdf0e10cSrcweir } 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir bool BiffWorkbookFragment::importWorkspaceFragment() 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir // enable workbook mode, has not been set yet in BIFF4 workspace files 447*cdf0e10cSrcweir setIsWorkbookFile(); 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir WorksheetBuffer& rWorksheets = getWorksheets(); 450*cdf0e10cSrcweir bool bRet = true; 451*cdf0e10cSrcweir 452*cdf0e10cSrcweir // import the workspace globals 453*cdf0e10cSrcweir ISegmentProgressBarRef xGlobalsProgress = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS ); 454*cdf0e10cSrcweir bool bLoop = true; 455*cdf0e10cSrcweir BiffInputStream& rStrm = getInputStream(); 456*cdf0e10cSrcweir while( bRet && bLoop && rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) ) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir switch( rStrm.getRecId() ) 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir case BIFF_ID_SHEET: rWorksheets.importSheet( rStrm ); break; 461*cdf0e10cSrcweir case BIFF_ID_CODEPAGE: setCodePage( rStrm.readuInt16() ); break; 462*cdf0e10cSrcweir case BIFF_ID_FILEPASS: bRet = getCodecHelper().importFilePass( rStrm ); break; 463*cdf0e10cSrcweir case BIFF_ID_SHEETHEADER: rStrm.rewindRecord(); bLoop = false; break; 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir } 466*cdf0e10cSrcweir xGlobalsProgress->setPosition( 1.0 ); 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir // load sheet fragments (do not return false in bRet on missing/broken sheets) 469*cdf0e10cSrcweir bool bNextSheet = bRet; 470*cdf0e10cSrcweir for( sal_Int32 nWorksheet = 0, nWorksheetCount = rWorksheets.getWorksheetCount(); bNextSheet && (nWorksheet < nWorksheetCount); ++nWorksheet ) 471*cdf0e10cSrcweir { 472*cdf0e10cSrcweir // try to start a new sheet fragment (with leading SHEETHEADER record) 473*cdf0e10cSrcweir bNextSheet = rStrm.startNextRecord() && (rStrm.getRecId() == BIFF_ID_SHEETHEADER); 474*cdf0e10cSrcweir if( bNextSheet ) 475*cdf0e10cSrcweir { 476*cdf0e10cSrcweir double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); 477*cdf0e10cSrcweir ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength ); 478*cdf0e10cSrcweir /* Read current sheet name (sheet substreams may not be in the 479*cdf0e10cSrcweir same order as SHEET records are). */ 480*cdf0e10cSrcweir rStrm.skip( 4 ); 481*cdf0e10cSrcweir OUString aSheetName = rStrm.readByteStringUC( false, getTextEncoding() ); 482*cdf0e10cSrcweir sal_Int16 nCurrSheet = rWorksheets.getCalcSheetIndex( aSheetName ); 483*cdf0e10cSrcweir // load the sheet fragment records 484*cdf0e10cSrcweir BiffFragmentType eSheetFragment = startFragment( getBiff() ); 485*cdf0e10cSrcweir bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCurrSheet ); 486*cdf0e10cSrcweir // do not return false in bRet on missing/broken sheets 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir } 489*cdf0e10cSrcweir 490*cdf0e10cSrcweir return bRet; 491*cdf0e10cSrcweir } 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgressBar ) 494*cdf0e10cSrcweir { 495*cdf0e10cSrcweir WorkbookSettings& rWorkbookSett = getWorkbookSettings(); 496*cdf0e10cSrcweir ViewSettings& rViewSett = getViewSettings(); 497*cdf0e10cSrcweir SharedStringsBuffer& rSharedStrings = getSharedStrings(); 498*cdf0e10cSrcweir StylesBuffer& rStyles = getStyles(); 499*cdf0e10cSrcweir WorksheetBuffer& rWorksheets = getWorksheets(); 500*cdf0e10cSrcweir PivotCacheBuffer& rPivotCaches = getPivotCaches(); 501*cdf0e10cSrcweir bool bHasVbaProject = false; 502*cdf0e10cSrcweir bool bEmptyVbaProject = false; 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir // collect records that need to be loaded in a second pass 505*cdf0e10cSrcweir typedef ::std::vector< sal_Int64 > RecordHandleVec; 506*cdf0e10cSrcweir RecordHandleVec aExtLinkRecs; 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir bool bRet = true; 509*cdf0e10cSrcweir bool bLoop = true; 510*cdf0e10cSrcweir BiffInputStream& rStrm = getInputStream(); 511*cdf0e10cSrcweir while( bRet && bLoop && rStrm.startNextRecord() ) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir sal_uInt16 nRecId = rStrm.getRecId(); 514*cdf0e10cSrcweir bool bExtLinkRec = false; 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir /* #i56376# BIFF5-BIFF8: If an EOF record for globals is missing, 517*cdf0e10cSrcweir simulate it. The issue is about a document where the sheet fragment 518*cdf0e10cSrcweir starts directly after the EXTSST record, without terminating the 519*cdf0e10cSrcweir globals fragment with an EOF record. */ 520*cdf0e10cSrcweir if( BiffHelper::isBofRecord( rStrm ) || (nRecId == BIFF_ID_EOF) ) 521*cdf0e10cSrcweir { 522*cdf0e10cSrcweir bLoop = false; 523*cdf0e10cSrcweir } 524*cdf0e10cSrcweir else switch( nRecId ) 525*cdf0e10cSrcweir { 526*cdf0e10cSrcweir // records in all BIFF versions 527*cdf0e10cSrcweir case BIFF_ID_CODEPAGE: setCodePage( rStrm.readuInt16() ); break; 528*cdf0e10cSrcweir case BIFF_ID_DATEMODE: rWorkbookSett.importDateMode( rStrm ); break; 529*cdf0e10cSrcweir case BIFF_ID_FILEPASS: bRet = getCodecHelper().importFilePass( rStrm ); break; 530*cdf0e10cSrcweir case BIFF_ID_PRECISION: rWorkbookSett.importPrecision( rStrm ); break; 531*cdf0e10cSrcweir case BIFF_ID_WINDOW1: rViewSett.importWindow1( rStrm ); break; 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir // BIFF specific records 534*cdf0e10cSrcweir default: switch( getBiff() ) 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir case BIFF2: switch( nRecId ) 537*cdf0e10cSrcweir { 538*cdf0e10cSrcweir case BIFF2_ID_DEFINEDNAME: bExtLinkRec = true; break; 539*cdf0e10cSrcweir case BIFF2_ID_EXTERNALNAME: bExtLinkRec = true; break; 540*cdf0e10cSrcweir case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; 541*cdf0e10cSrcweir case BIFF2_ID_FONT: rStyles.importFont( rStrm ); break; 542*cdf0e10cSrcweir case BIFF_ID_FONTCOLOR: rStyles.importFontColor( rStrm ); break; 543*cdf0e10cSrcweir case BIFF2_ID_FORMAT: rStyles.importFormat( rStrm ); break; 544*cdf0e10cSrcweir case BIFF2_ID_XF: rStyles.importXf( rStrm ); break; 545*cdf0e10cSrcweir } 546*cdf0e10cSrcweir break; 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir case BIFF3: switch( nRecId ) 549*cdf0e10cSrcweir { 550*cdf0e10cSrcweir case BIFF_ID_CRN: bExtLinkRec = true; break; 551*cdf0e10cSrcweir case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break; 552*cdf0e10cSrcweir case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break; 553*cdf0e10cSrcweir case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; 554*cdf0e10cSrcweir case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( rStrm ); break; 555*cdf0e10cSrcweir case BIFF3_ID_FONT: rStyles.importFont( rStrm ); break; 556*cdf0e10cSrcweir case BIFF2_ID_FORMAT: rStyles.importFormat( rStrm ); break; 557*cdf0e10cSrcweir case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( rStrm ); break; 558*cdf0e10cSrcweir case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break; 559*cdf0e10cSrcweir case BIFF_ID_STYLE: rStyles.importStyle( rStrm ); break; 560*cdf0e10cSrcweir case BIFF_ID_XCT: bExtLinkRec = true; break; 561*cdf0e10cSrcweir case BIFF3_ID_XF: rStyles.importXf( rStrm ); break; 562*cdf0e10cSrcweir } 563*cdf0e10cSrcweir break; 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir case BIFF4: switch( nRecId ) 566*cdf0e10cSrcweir { 567*cdf0e10cSrcweir case BIFF_ID_CRN: bExtLinkRec = true; break; 568*cdf0e10cSrcweir case BIFF3_ID_DEFINEDNAME: bExtLinkRec = true; break; 569*cdf0e10cSrcweir case BIFF3_ID_EXTERNALNAME: bExtLinkRec = true; break; 570*cdf0e10cSrcweir case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; 571*cdf0e10cSrcweir case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( rStrm ); break; 572*cdf0e10cSrcweir case BIFF3_ID_FONT: rStyles.importFont( rStrm ); break; 573*cdf0e10cSrcweir case BIFF4_ID_FORMAT: rStyles.importFormat( rStrm ); break; 574*cdf0e10cSrcweir case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( rStrm ); break; 575*cdf0e10cSrcweir case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break; 576*cdf0e10cSrcweir case BIFF_ID_STYLE: rStyles.importStyle( rStrm ); break; 577*cdf0e10cSrcweir case BIFF_ID_XCT: bExtLinkRec = true; break; 578*cdf0e10cSrcweir case BIFF4_ID_XF: rStyles.importXf( rStrm ); break; 579*cdf0e10cSrcweir } 580*cdf0e10cSrcweir break; 581*cdf0e10cSrcweir 582*cdf0e10cSrcweir case BIFF5: switch( nRecId ) 583*cdf0e10cSrcweir { 584*cdf0e10cSrcweir case BIFF_ID_BOOKBOOL: rWorkbookSett.importBookBool( rStrm ); break; 585*cdf0e10cSrcweir case BIFF_ID_CRN: bExtLinkRec = true; break; 586*cdf0e10cSrcweir case BIFF5_ID_DEFINEDNAME: bExtLinkRec = true; break; 587*cdf0e10cSrcweir case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break; 588*cdf0e10cSrcweir case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; 589*cdf0e10cSrcweir case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( rStrm ); break; 590*cdf0e10cSrcweir case BIFF5_ID_FONT: rStyles.importFont( rStrm ); break; 591*cdf0e10cSrcweir case BIFF4_ID_FORMAT: rStyles.importFormat( rStrm ); break; 592*cdf0e10cSrcweir case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( rStrm ); break; 593*cdf0e10cSrcweir case BIFF_ID_OLESIZE: rViewSett.importOleSize( rStrm ); break; 594*cdf0e10cSrcweir case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break; 595*cdf0e10cSrcweir case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( rStrm ); break; 596*cdf0e10cSrcweir case BIFF_ID_SHEET: rWorksheets.importSheet( rStrm ); break; 597*cdf0e10cSrcweir case BIFF_ID_STYLE: rStyles.importStyle( rStrm ); break; 598*cdf0e10cSrcweir case BIFF_ID_XCT: bExtLinkRec = true; break; 599*cdf0e10cSrcweir case BIFF5_ID_XF: rStyles.importXf( rStrm ); break; 600*cdf0e10cSrcweir } 601*cdf0e10cSrcweir break; 602*cdf0e10cSrcweir 603*cdf0e10cSrcweir case BIFF8: switch( nRecId ) 604*cdf0e10cSrcweir { 605*cdf0e10cSrcweir case BIFF_ID_BOOKBOOL: rWorkbookSett.importBookBool( rStrm ); break; 606*cdf0e10cSrcweir case BIFF_ID_CODENAME: rWorkbookSett.importCodeName( rStrm ); break; 607*cdf0e10cSrcweir case BIFF_ID_CRN: bExtLinkRec = true; break; 608*cdf0e10cSrcweir case BIFF5_ID_DEFINEDNAME: bExtLinkRec = true; break; 609*cdf0e10cSrcweir case BIFF_ID_EXTERNALBOOK: bExtLinkRec = true; break; 610*cdf0e10cSrcweir case BIFF5_ID_EXTERNALNAME: bExtLinkRec = true; break; 611*cdf0e10cSrcweir case BIFF_ID_EXTERNSHEET: bExtLinkRec = true; break; 612*cdf0e10cSrcweir case BIFF_ID_FILESHARING: rWorkbookSett.importFileSharing( rStrm ); break; 613*cdf0e10cSrcweir case BIFF5_ID_FONT: rStyles.importFont( rStrm ); break; 614*cdf0e10cSrcweir case BIFF4_ID_FORMAT: rStyles.importFormat( rStrm ); break; 615*cdf0e10cSrcweir case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( rStrm ); break; 616*cdf0e10cSrcweir case BIFF_ID_OLESIZE: rViewSett.importOleSize( rStrm ); break; 617*cdf0e10cSrcweir case BIFF_ID_PALETTE: rStyles.importPalette( rStrm ); break; 618*cdf0e10cSrcweir case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( rStrm ); break; 619*cdf0e10cSrcweir case BIFF_ID_SHEET: rWorksheets.importSheet( rStrm ); break; 620*cdf0e10cSrcweir case BIFF_ID_SST: rSharedStrings.importSst( rStrm ); break; 621*cdf0e10cSrcweir case BIFF_ID_STYLE: rStyles.importStyle( rStrm ); break; 622*cdf0e10cSrcweir case BIFF_ID_USESELFS: rWorkbookSett.importUsesElfs( rStrm ); break; 623*cdf0e10cSrcweir case BIFF_ID_VBAPROJECT: bHasVbaProject = true; break; 624*cdf0e10cSrcweir case BIFF_ID_VBAPROJECTEMPTY: bEmptyVbaProject = true; break; 625*cdf0e10cSrcweir case BIFF_ID_XCT: bExtLinkRec = true; break; 626*cdf0e10cSrcweir case BIFF5_ID_XF: rStyles.importXf( rStrm ); break; 627*cdf0e10cSrcweir } 628*cdf0e10cSrcweir break; 629*cdf0e10cSrcweir 630*cdf0e10cSrcweir case BIFF_UNKNOWN: break; 631*cdf0e10cSrcweir } 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir if( bExtLinkRec ) 635*cdf0e10cSrcweir aExtLinkRecs.push_back( rStrm.getRecHandle() ); 636*cdf0e10cSrcweir } 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir // finalize global buffers 639*cdf0e10cSrcweir rProgressBar.setPosition( 0.5 ); 640*cdf0e10cSrcweir if( bRet ) 641*cdf0e10cSrcweir { 642*cdf0e10cSrcweir rSharedStrings.finalizeImport(); 643*cdf0e10cSrcweir rStyles.finalizeImport(); 644*cdf0e10cSrcweir } 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir /* Import external link data (EXTERNSHEET, EXTERNALNAME, DEFINEDNAME) 647*cdf0e10cSrcweir which need existing internal sheets (SHEET records). The SHEET records 648*cdf0e10cSrcweir may follow the external links records in some BIFF versions. */ 649*cdf0e10cSrcweir if( bRet && !aExtLinkRecs.empty() ) 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir // remember current stream position (the EOF record) 652*cdf0e10cSrcweir sal_Int64 nEofHandle = rStrm.getRecHandle(); 653*cdf0e10cSrcweir // context handler implementing import of external link records 654*cdf0e10cSrcweir BiffExternalSheetDataContext aSheetContext( *this, true ); 655*cdf0e10cSrcweir // import all records by using their cached record handle 656*cdf0e10cSrcweir for( RecordHandleVec::const_iterator aIt = aExtLinkRecs.begin(), aEnd = aExtLinkRecs.end(); (aIt != aEnd) && rStrm.startRecordByHandle( *aIt ); ++aIt ) 657*cdf0e10cSrcweir aSheetContext.importRecord( rStrm ); 658*cdf0e10cSrcweir // finalize global buffers 659*cdf0e10cSrcweir getDefinedNames().finalizeImport(); 660*cdf0e10cSrcweir // seek back to the EOF record of the workbook globals fragment 661*cdf0e10cSrcweir bRet = rStrm.startRecordByHandle( nEofHandle ); 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir 664*cdf0e10cSrcweir // open the VBA project storage 665*cdf0e10cSrcweir if( bHasVbaProject && !bEmptyVbaProject ) 666*cdf0e10cSrcweir setVbaProjectStorage( getBaseFilter().openSubStorage( CREATE_OUSTRING( "_VBA_PROJECT_CUR" ), false ) ); 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir // #i56376# missing EOF - rewind before worksheet BOF record (see above) 669*cdf0e10cSrcweir if( bRet && BiffHelper::isBofRecord( rStrm ) ) 670*cdf0e10cSrcweir rStrm.rewindRecord(); 671*cdf0e10cSrcweir 672*cdf0e10cSrcweir rProgressBar.setPosition( 1.0 ); 673*cdf0e10cSrcweir return bRet; 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir bool BiffWorkbookFragment::importSheetFragment( ISegmentProgressBar& rProgressBar, BiffFragmentType eFragment, sal_Int16 nCalcSheet ) 677*cdf0e10cSrcweir { 678*cdf0e10cSrcweir // no Calc sheet - skip the fragment 679*cdf0e10cSrcweir if( nCalcSheet < 0 ) 680*cdf0e10cSrcweir return skipFragment(); 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir // find the sheet type for this fragment 683*cdf0e10cSrcweir WorksheetType eSheetType = SHEETTYPE_EMPTYSHEET; 684*cdf0e10cSrcweir switch( eFragment ) 685*cdf0e10cSrcweir { 686*cdf0e10cSrcweir case BIFF_FRAGMENT_WORKSHEET: eSheetType = SHEETTYPE_WORKSHEET; break; 687*cdf0e10cSrcweir case BIFF_FRAGMENT_CHARTSHEET: eSheetType = SHEETTYPE_CHARTSHEET; break; 688*cdf0e10cSrcweir case BIFF_FRAGMENT_MACROSHEET: eSheetType = SHEETTYPE_MACROSHEET; break; 689*cdf0e10cSrcweir case BIFF_FRAGMENT_MODULESHEET: eSheetType = SHEETTYPE_MODULESHEET; break; 690*cdf0e10cSrcweir case BIFF_FRAGMENT_EMPTYSHEET: eSheetType = SHEETTYPE_EMPTYSHEET; break; 691*cdf0e10cSrcweir default: return false; 692*cdf0e10cSrcweir } 693*cdf0e10cSrcweir 694*cdf0e10cSrcweir /* #i11183# Clear buffers that are used per-sheet, e.g. external links in 695*cdf0e10cSrcweir BIFF4W and BIFF5 files, or defined names in BIFF4W files. */ 696*cdf0e10cSrcweir createBuffersPerSheet( nCalcSheet ); 697*cdf0e10cSrcweir 698*cdf0e10cSrcweir // preprocess some records 699*cdf0e10cSrcweir BiffInputStream& rStrm = getInputStream(); 700*cdf0e10cSrcweir switch( getBiff() ) 701*cdf0e10cSrcweir { 702*cdf0e10cSrcweir // load the workbook globals fragment records in BIFF2-BIFF4 703*cdf0e10cSrcweir case BIFF2: 704*cdf0e10cSrcweir case BIFF3: 705*cdf0e10cSrcweir case BIFF4: 706*cdf0e10cSrcweir { 707*cdf0e10cSrcweir // remember current record to seek back below 708*cdf0e10cSrcweir sal_Int64 nRecHandle = rStrm.getRecHandle(); 709*cdf0e10cSrcweir // import the global records 710*cdf0e10cSrcweir ISegmentProgressBarRef xGlobalsProgress = rProgressBar.createSegment( PROGRESS_LENGTH_GLOBALS ); 711*cdf0e10cSrcweir importGlobalsFragment( *xGlobalsProgress ); 712*cdf0e10cSrcweir // rewind stream to fragment BOF record 713*cdf0e10cSrcweir rStrm.startRecordByHandle( nRecHandle ); 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir break; 716*cdf0e10cSrcweir 717*cdf0e10cSrcweir // load the external link records for this sheet in BIFF5 718*cdf0e10cSrcweir case BIFF5: 719*cdf0e10cSrcweir { 720*cdf0e10cSrcweir // remember current record to seek back below 721*cdf0e10cSrcweir sal_Int64 nRecHandle = rStrm.getRecHandle(); 722*cdf0e10cSrcweir // fragment implementing import of external link records 723*cdf0e10cSrcweir BiffExternalLinkFragment( *this ).importFragment(); 724*cdf0e10cSrcweir // rewind stream to fragment BOF record 725*cdf0e10cSrcweir rStrm.startRecordByHandle( nRecHandle ); 726*cdf0e10cSrcweir } 727*cdf0e10cSrcweir break; 728*cdf0e10cSrcweir 729*cdf0e10cSrcweir case BIFF8: 730*cdf0e10cSrcweir break; 731*cdf0e10cSrcweir 732*cdf0e10cSrcweir case BIFF_UNKNOWN: 733*cdf0e10cSrcweir break; 734*cdf0e10cSrcweir } 735*cdf0e10cSrcweir 736*cdf0e10cSrcweir // create the WorksheetGlobals object 737*cdf0e10cSrcweir ISegmentProgressBarRef xSheetProgress = rProgressBar.createSegment( rProgressBar.getFreeLength() ); 738*cdf0e10cSrcweir WorksheetGlobalsRef xSheetGlob = WorksheetHelper::constructGlobals( *this, xSheetProgress, eSheetType, nCalcSheet ); 739*cdf0e10cSrcweir OSL_ENSURE( xSheetGlob.get(), "BiffWorkbookFragment::importSheetFragment - missing sheet in document" ); 740*cdf0e10cSrcweir if( !xSheetGlob.get() ) 741*cdf0e10cSrcweir return false; 742*cdf0e10cSrcweir 743*cdf0e10cSrcweir // create the worksheet fragment 744*cdf0e10cSrcweir ::boost::shared_ptr< BiffWorksheetFragmentBase > xFragment; 745*cdf0e10cSrcweir switch( eSheetType ) 746*cdf0e10cSrcweir { 747*cdf0e10cSrcweir case SHEETTYPE_WORKSHEET: 748*cdf0e10cSrcweir case SHEETTYPE_MACROSHEET: 749*cdf0e10cSrcweir case SHEETTYPE_DIALOGSHEET: 750*cdf0e10cSrcweir xFragment.reset( new BiffWorksheetFragment( *xSheetGlob, *this ) ); 751*cdf0e10cSrcweir break; 752*cdf0e10cSrcweir case SHEETTYPE_CHARTSHEET: 753*cdf0e10cSrcweir xFragment.reset( new BiffChartsheetFragment( *xSheetGlob, *this ) ); 754*cdf0e10cSrcweir break; 755*cdf0e10cSrcweir case SHEETTYPE_MODULESHEET: 756*cdf0e10cSrcweir case SHEETTYPE_EMPTYSHEET: 757*cdf0e10cSrcweir xFragment.reset( new BiffSkipWorksheetFragment( *xSheetGlob, *this ) ); 758*cdf0e10cSrcweir break; 759*cdf0e10cSrcweir } 760*cdf0e10cSrcweir // load the sheet fragment records 761*cdf0e10cSrcweir return xFragment.get() && xFragment->importFragment(); 762*cdf0e10cSrcweir } 763*cdf0e10cSrcweir 764*cdf0e10cSrcweir // ============================================================================ 765*cdf0e10cSrcweir 766*cdf0e10cSrcweir } // namespace xls 767*cdf0e10cSrcweir } // namespace oox 768