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