xref: /AOO41X/main/oox/source/xls/workbookhelper.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "oox/xls/workbookhelper.hxx"
29 
30 #include <com/sun/star/container/XIndexAccess.hpp>
31 #include <com/sun/star/container/XNameContainer.hpp>
32 #include <com/sun/star/document/XActionLockable.hpp>
33 #include <com/sun/star/sheet/XDatabaseRange.hpp>
34 #include <com/sun/star/sheet/XDatabaseRanges.hpp>
35 #include <com/sun/star/sheet/XNamedRange.hpp>
36 #include <com/sun/star/sheet/XNamedRanges.hpp>
37 #include <com/sun/star/sheet/XSpreadsheet.hpp>
38 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
39 #include <com/sun/star/style/XStyle.hpp>
40 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
41 #include <com/sun/star/table/CellAddress.hpp>
42 #include <osl/thread.h>
43 #include "oox/drawingml/theme.hxx"
44 #include "oox/helper/progressbar.hxx"
45 #include "oox/helper/propertyset.hxx"
46 #include "oox/ole/vbaproject.hxx"
47 #include "oox/xls/addressconverter.hxx"
48 #include "oox/xls/biffinputstream.hxx"
49 #include "oox/xls/biffcodec.hxx"
50 #include "oox/xls/connectionsbuffer.hxx"
51 #include "oox/xls/defnamesbuffer.hxx"
52 #include "oox/xls/excelchartconverter.hxx"
53 #include "oox/xls/excelfilter.hxx"
54 #include "oox/xls/externallinkbuffer.hxx"
55 #include "oox/xls/formulaparser.hxx"
56 #include "oox/xls/pagesettings.hxx"
57 #include "oox/xls/pivotcachebuffer.hxx"
58 #include "oox/xls/pivottablebuffer.hxx"
59 #include "oox/xls/scenariobuffer.hxx"
60 #include "oox/xls/sharedstringsbuffer.hxx"
61 #include "oox/xls/stylesbuffer.hxx"
62 #include "oox/xls/tablebuffer.hxx"
63 #include "oox/xls/themebuffer.hxx"
64 #include "oox/xls/unitconverter.hxx"
65 #include "oox/xls/viewsettings.hxx"
66 #include "oox/xls/workbooksettings.hxx"
67 #include "oox/xls/worksheetbuffer.hxx"
68 
69 namespace oox {
70 namespace xls {
71 
72 // ============================================================================
73 
74 using namespace ::com::sun::star::awt;
75 using namespace ::com::sun::star::container;
76 using namespace ::com::sun::star::document;
77 using namespace ::com::sun::star::lang;
78 using namespace ::com::sun::star::sheet;
79 using namespace ::com::sun::star::style;
80 using namespace ::com::sun::star::table;
81 using namespace ::com::sun::star::uno;
82 
83 using ::oox::core::BinaryFilterBase;
84 using ::oox::core::FilterBase;
85 using ::oox::core::FragmentHandler;
86 using ::oox::core::XmlFilterBase;
87 using ::oox::drawingml::Theme;
88 using ::rtl::OUString;
89 
90 // ============================================================================
91 
92 bool IgnoreCaseCompare::operator()( const OUString& rName1, const OUString& rName2 ) const
93 {
94     // there is no wrapper in rtl::OUString, TODO: compare with collator
95     return ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
96         rName1.getStr(), rName1.getLength(), rName2.getStr(), rName2.getLength() ) < 0;
97 }
98 
99 // ============================================================================
100 
101 class WorkbookGlobals
102 {
103 public:
104     explicit            WorkbookGlobals( ExcelFilter& rFilter );
105     explicit            WorkbookGlobals( ExcelBiffFilter& rFilter, BiffType eBiff );
106                         ~WorkbookGlobals();
107 
108     /** Returns true, if this helper refers to a valid document. */
109     inline bool         isValid() const { return mxDoc.is(); }
110 
111     // filter -----------------------------------------------------------------
112 
113     /** Returns the base filter object (base class of all filters). */
114     inline FilterBase&  getBaseFilter() const { return mrBaseFilter; }
115     /** Returns the filter progress bar. */
116     inline SegmentProgressBar& getProgressBar() const { return *mxProgressBar; }
117     /** Returns the file type of the current filter. */
118     inline FilterType   getFilterType() const { return meFilterType; }
119     /** Returns true, if the file is a multi-sheet document, or false if single-sheet. */
120     inline bool         isWorkbookFile() const { return mbWorkbook; }
121     /** Returns the VBA project storage. */
122     inline StorageRef   getVbaProjectStorage() const { return mxVbaPrjStrg; }
123     /** Returns the index of the current Calc sheet, if filter currently processes a sheet. */
124     inline sal_Int16    getCurrentSheetIndex() const { return mnCurrSheet; }
125 
126     /** Sets the VBA project storage used to import VBA source code and forms. */
127     inline void         setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { mxVbaPrjStrg = rxVbaPrjStrg; }
128     /** Sets the index of the current Calc sheet, if filter currently processes a sheet. */
129     inline void         setCurrentSheetIndex( sal_Int16 nSheet ) { mnCurrSheet = nSheet; }
130 
131     // document model ---------------------------------------------------------
132 
133     /** Returns a reference to the source/target spreadsheet document model. */
134     inline Reference< XSpreadsheetDocument > getDocument() const { return mxDoc; }
135     /** Returns the cell or page styles container from the Calc document. */
136     Reference< XNameContainer > getStyleFamily( bool bPageStyles ) const;
137     /** Returns the specified cell or page style from the Calc document. */
138     Reference< XStyle > getStyleObject( const OUString& rStyleName, bool bPageStyle ) const;
139     /** Creates and returns a defined name on-the-fly in the Calc document. */
140     Reference< XNamedRange > createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const;
141     /** Creates and returns a database range on-the-fly in the Calc document. */
142     Reference< XDatabaseRange > createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const;
143     /** Creates and returns a com.sun.star.style.Style object for cells or pages. */
144     Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle ) const;
145 
146     // buffers ----------------------------------------------------------------
147 
148     /** Returns the global workbook settings object. */
149     inline WorkbookSettings& getWorkbookSettings() const { return *mxWorkbookSettings; }
150     /** Returns the workbook and sheet view settings object. */
151     inline ViewSettings& getViewSettings() const { return *mxViewSettings; }
152     /** Returns the worksheet buffer containing sheet names and properties. */
153     inline WorksheetBuffer& getWorksheets() const { return *mxWorksheets; }
154     /** Returns the office theme object read from the theme substorage. */
155     inline ThemeBuffer& getTheme() const { return *mxTheme; }
156     /** Returns all cell formatting objects read from the styles substream. */
157     inline StylesBuffer& getStyles() const { return *mxStyles; }
158     /** Returns the shared strings read from the shared strings substream. */
159     inline SharedStringsBuffer& getSharedStrings() const { return *mxSharedStrings; }
160     /** Returns the external links read from the external links substream. */
161     inline ExternalLinkBuffer& getExternalLinks() const { return *mxExtLinks; }
162     /** Returns the defined names read from the workbook globals. */
163     inline DefinedNamesBuffer& getDefinedNames() const { return *mxDefNames; }
164     /** Returns the tables collection (equivalent to Calc's database ranges). */
165     inline TableBuffer& getTables() const { return *mxTables; }
166     /** Returns the scenarios collection. */
167     inline ScenarioBuffer& getScenarios() const { return *mxScenarios; }
168     /** Returns the collection of external data connections. */
169     inline ConnectionsBuffer&  getConnections() const { return *mxConnections; }
170     /** Returns the collection of pivot caches. */
171     inline PivotCacheBuffer& getPivotCaches() const { return *mxPivotCaches; }
172     /** Returns the collection of pivot tables. */
173     inline PivotTableBuffer& getPivotTables() { return *mxPivotTables; }
174 
175     // converters -------------------------------------------------------------
176 
177     /** Returns the import formula parser. */
178     inline FormulaParser& getFormulaParser() const { return *mxFmlaParser; }
179     /** Returns the measurement unit converter. */
180     inline UnitConverter& getUnitConverter() const { return *mxUnitConverter; }
181     /** Returns the converter for string to cell address/range conversion. */
182     inline AddressConverter& getAddressConverter() const { return *mxAddrConverter; }
183     /** Returns the chart object converter. */
184     inline ExcelChartConverter& getChartConverter() const { return *mxChartConverter; }
185     /** Returns the page/print settings converter. */
186     inline PageSettingsConverter& getPageSettingsConverter() const { return *mxPageSettConverter; }
187 
188     // OOXML/BIFF12 specific --------------------------------------------------
189 
190     /** Returns the base OOXML/BIFF12 filter object. */
191     inline XmlFilterBase& getOoxFilter() const { return *mpOoxFilter; }
192 
193     // BIFF2-BIFF8 specific ---------------------------------------------------
194 
195     /** Returns the base BIFF filter object. */
196     inline BinaryFilterBase& getBiffFilter() const { return *mpBiffFilter; }
197     /** Returns the BIFF type in binary filter. */
198     inline BiffType     getBiff() const { return meBiff; }
199     /** Returns the text encoding used to import/export byte strings. */
200     inline rtl_TextEncoding getTextEncoding() const { return meTextEnc; }
201     /** Sets the text encoding to import/export byte strings. */
202     void                setTextEncoding( rtl_TextEncoding eTextEnc );
203     /** Sets code page read from a CODEPAGE record for byte string import. */
204     void                setCodePage( sal_uInt16 nCodePage );
205     /** Sets text encoding from the default application font, if CODEPAGE record is missing. */
206     void                setAppFontEncoding( rtl_TextEncoding eAppFontEnc );
207     /** Enables workbook file mode, used for BIFF4 workspace files. */
208     void                setIsWorkbookFile();
209     /** Recreates global buffers that are used per sheet in specific BIFF versions. */
210     void                createBuffersPerSheet( sal_Int16 nSheet );
211     /** Returns the codec helper that stores the encoder/decoder object. */
212     inline BiffCodecHelper& getCodecHelper() { return *mxCodecHelper; }
213 
214 private:
215     /** Initializes some basic members and sets needed document properties. */
216     void                initialize( bool bWorkbookFile );
217     /** Finalizes the filter process (sets some needed document properties). */
218     void                finalize();
219 
220 private:
221     typedef ::std::auto_ptr< SegmentProgressBar >       ProgressBarPtr;
222     typedef ::std::auto_ptr< WorkbookSettings >         WorkbookSettPtr;
223     typedef ::std::auto_ptr< ViewSettings >             ViewSettingsPtr;
224     typedef ::std::auto_ptr< WorksheetBuffer >          WorksheetBfrPtr;
225     typedef ::boost::shared_ptr< ThemeBuffer >          ThemeBfrRef;
226     typedef ::std::auto_ptr< StylesBuffer >             StylesBfrPtr;
227     typedef ::std::auto_ptr< SharedStringsBuffer >      SharedStrBfrPtr;
228     typedef ::std::auto_ptr< ExternalLinkBuffer >       ExtLinkBfrPtr;
229     typedef ::std::auto_ptr< DefinedNamesBuffer >       DefNamesBfrPtr;
230     typedef ::std::auto_ptr< TableBuffer >              TableBfrPtr;
231     typedef ::std::auto_ptr< ScenarioBuffer >           ScenarioBfrPtr;
232     typedef ::std::auto_ptr< ConnectionsBuffer >        ConnectionsBfrPtr;
233     typedef ::std::auto_ptr< PivotCacheBuffer >         PivotCacheBfrPtr;
234     typedef ::std::auto_ptr< PivotTableBuffer >         PivotTableBfrPtr;
235     typedef ::std::auto_ptr< FormulaParser >            FormulaParserPtr;
236     typedef ::std::auto_ptr< UnitConverter >            UnitConvPtr;
237     typedef ::std::auto_ptr< AddressConverter >         AddressConvPtr;
238     typedef ::std::auto_ptr< ExcelChartConverter >      ExcelChartConvPtr;
239     typedef ::std::auto_ptr< PageSettingsConverter >    PageSettConvPtr;
240     typedef ::std::auto_ptr< BiffCodecHelper >          BiffCodecHelperPtr;
241 
242     OUString            maCellStyles;           /// Style family name for cell styles.
243     OUString            maPageStyles;           /// Style family name for page styles.
244     OUString            maCellStyleServ;        /// Service name for a cell style.
245     OUString            maPageStyleServ;        /// Service name for a page style.
246     Reference< XSpreadsheetDocument > mxDoc;    /// Document model.
247     FilterBase&         mrBaseFilter;           /// Base filter object.
248     ExcelFilterBase&    mrExcelBase;            /// Base object for registration of this structure.
249     FilterType          meFilterType;           /// File type of the filter.
250     ProgressBarPtr      mxProgressBar;          /// The progress bar.
251     StorageRef          mxVbaPrjStrg;           /// Storage containing the VBA project.
252     sal_Int16           mnCurrSheet;            /// Current sheet index in Calc dcument.
253     bool                mbWorkbook;             /// True = multi-sheet file.
254 
255     // buffers
256     WorkbookSettPtr     mxWorkbookSettings;     /// Global workbook settings.
257     ViewSettingsPtr     mxViewSettings;         /// Workbook and sheet view settings.
258     WorksheetBfrPtr     mxWorksheets;           /// Sheet info buffer.
259     ThemeBfrRef         mxTheme;                /// Formatting theme from theme substream.
260     StylesBfrPtr        mxStyles;               /// All cell style objects from styles substream.
261     SharedStrBfrPtr     mxSharedStrings;        /// All strings from shared strings substream.
262     ExtLinkBfrPtr       mxExtLinks;             /// All external links.
263     DefNamesBfrPtr      mxDefNames;             /// All defined names.
264     TableBfrPtr         mxTables;               /// All tables (database ranges).
265     ScenarioBfrPtr      mxScenarios;            /// All scenarios.
266     ConnectionsBfrPtr   mxConnections;          /// All external data connections.
267     PivotCacheBfrPtr    mxPivotCaches;          /// All pivot caches in the document.
268     PivotTableBfrPtr    mxPivotTables;          /// All pivot tables in the document.
269 
270     // converters
271     FormulaParserPtr    mxFmlaParser;           /// Import formula parser.
272     UnitConvPtr         mxUnitConverter;        /// General unit converter.
273     AddressConvPtr      mxAddrConverter;        /// Cell address and cell range address converter.
274     ExcelChartConvPtr   mxChartConverter;       /// Chart object converter.
275     PageSettConvPtr     mxPageSettConverter;    /// Page/print settings converter.
276 
277     // OOXML/BIFF12 specific
278     XmlFilterBase*      mpOoxFilter;            /// Base OOXML/BIFF12 filter object.
279 
280     // BIFF2-BIFF8 specific
281     BinaryFilterBase*   mpBiffFilter;           /// Base BIFF2-BIFF8 filter object.
282     BiffCodecHelperPtr  mxCodecHelper;          /// Encoder/decoder helper.
283     BiffType            meBiff;                 /// BIFF version for BIFF import/export.
284     rtl_TextEncoding    meTextEnc;              /// BIFF byte string text encoding.
285     bool                mbHasCodePage;          /// True = CODEPAGE record exists in imported stream.
286 };
287 
288 // ----------------------------------------------------------------------------
289 
290 WorkbookGlobals::WorkbookGlobals( ExcelFilter& rFilter ) :
291     mrBaseFilter( rFilter ),
292     mrExcelBase( rFilter ),
293     meFilterType( FILTER_OOXML ),
294     mpOoxFilter( &rFilter ),
295     mpBiffFilter( 0 ),
296     meBiff( BIFF_UNKNOWN )
297 {
298     // register at the filter, needed for virtual callbacks (even during construction)
299     mrExcelBase.registerWorkbookGlobals( *this );
300     initialize( true );
301 }
302 
303 WorkbookGlobals::WorkbookGlobals( ExcelBiffFilter& rFilter, BiffType eBiff ) :
304     mrBaseFilter( rFilter ),
305     mrExcelBase( rFilter ),
306     meFilterType( FILTER_BIFF ),
307     mpOoxFilter( 0 ),
308     mpBiffFilter( &rFilter ),
309     meBiff( eBiff )
310 {
311     // register at the filter, needed for virtual callbacks (even during construction)
312     mrExcelBase.registerWorkbookGlobals( *this );
313     initialize( eBiff >= BIFF5 );
314 }
315 
316 WorkbookGlobals::~WorkbookGlobals()
317 {
318     finalize();
319     mrExcelBase.unregisterWorkbookGlobals();
320 }
321 
322 // document model -------------------------------------------------------------
323 
324 Reference< XNameContainer > WorkbookGlobals::getStyleFamily( bool bPageStyles ) const
325 {
326     Reference< XNameContainer > xStylesNC;
327     try
328     {
329         Reference< XStyleFamiliesSupplier > xFamiliesSup( mxDoc, UNO_QUERY_THROW );
330         Reference< XNameAccess > xFamiliesNA( xFamiliesSup->getStyleFamilies(), UNO_QUERY_THROW );
331         xStylesNC.set( xFamiliesNA->getByName( bPageStyles ? maPageStyles : maCellStyles ), UNO_QUERY );
332     }
333     catch( Exception& )
334     {
335     }
336     OSL_ENSURE( xStylesNC.is(), "WorkbookGlobals::getStyleFamily - cannot access style family" );
337     return xStylesNC;
338 }
339 
340 Reference< XStyle > WorkbookGlobals::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
341 {
342     Reference< XStyle > xStyle;
343     try
344     {
345         Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
346         xStyle.set( xStylesNC->getByName( rStyleName ), UNO_QUERY );
347     }
348     catch( Exception& )
349     {
350     }
351     OSL_ENSURE( xStyle.is(), "WorkbookGlobals::getStyleObject - cannot access style object" );
352     return xStyle;
353 }
354 
355 Reference< XNamedRange > WorkbookGlobals::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const
356 {
357     // create the name and insert it into the Calc document
358     Reference< XNamedRange > xNamedRange;
359     if( orName.getLength() > 0 ) try
360     {
361         // find an unused name
362         PropertySet aDocProps( mxDoc );
363         Reference< XNamedRanges > xNamedRanges( aDocProps.getAnyProperty( PROP_NamedRanges ), UNO_QUERY_THROW );
364         Reference< XNameAccess > xNameAccess( xNamedRanges, UNO_QUERY_THROW );
365         orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' );
366         // create the named range
367         xNamedRanges->addNewByName( orName, OUString(), CellAddress( 0, 0, 0 ), nNameFlags );
368         xNamedRange.set( xNamedRanges->getByName( orName ), UNO_QUERY );
369     }
370     catch( Exception& )
371     {
372     }
373     OSL_ENSURE( xNamedRange.is(), "WorkbookGlobals::createNamedRangeObject - cannot create defined name" );
374     return xNamedRange;
375 }
376 
377 Reference< XDatabaseRange > WorkbookGlobals::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const
378 {
379     // validate cell range
380     CellRangeAddress aDestRange = rRangeAddr;
381     bool bValidRange = getAddressConverter().validateCellRange( aDestRange, true, true );
382 
383     // create database range and insert it into the Calc document
384     Reference< XDatabaseRange > xDatabaseRange;
385     if( bValidRange && (orName.getLength() > 0) ) try
386     {
387         // find an unused name
388         PropertySet aDocProps( mxDoc );
389         Reference< XDatabaseRanges > xDatabaseRanges( aDocProps.getAnyProperty( PROP_DatabaseRanges ), UNO_QUERY_THROW );
390         Reference< XNameAccess > xNameAccess( xDatabaseRanges, UNO_QUERY_THROW );
391         orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' );
392         // create the database range
393         xDatabaseRanges->addNewByName( orName, aDestRange );
394         xDatabaseRange.set( xDatabaseRanges->getByName( orName ), UNO_QUERY );
395     }
396     catch( Exception& )
397     {
398     }
399     OSL_ENSURE( xDatabaseRange.is(), "WorkbookGlobals::createDatabaseRangeObject - cannot create database range" );
400     return xDatabaseRange;
401 }
402 
403 Reference< XStyle > WorkbookGlobals::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
404 {
405     Reference< XStyle > xStyle;
406     try
407     {
408         Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW );
409         xStyle.set( mrBaseFilter.getModelFactory()->createInstance( bPageStyle ? maPageStyleServ : maCellStyleServ ), UNO_QUERY_THROW );
410         orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, orStyleName, ' ', Any( xStyle ), false );
411     }
412     catch( Exception& )
413     {
414     }
415     OSL_ENSURE( xStyle.is(), "WorkbookGlobals::createStyleObject - cannot create style" );
416     return xStyle;
417 }
418 
419 // BIFF specific --------------------------------------------------------------
420 
421 void WorkbookGlobals::setTextEncoding( rtl_TextEncoding eTextEnc )
422 {
423     if( eTextEnc != RTL_TEXTENCODING_DONTKNOW )
424         meTextEnc = eTextEnc;
425 }
426 
427 void WorkbookGlobals::setCodePage( sal_uInt16 nCodePage )
428 {
429     setTextEncoding( BiffHelper::calcTextEncodingFromCodePage( nCodePage ) );
430     mbHasCodePage = true;
431 }
432 
433 void WorkbookGlobals::setAppFontEncoding( rtl_TextEncoding eAppFontEnc )
434 {
435     if( !mbHasCodePage )
436         setTextEncoding( eAppFontEnc );
437 }
438 
439 void WorkbookGlobals::setIsWorkbookFile()
440 {
441     OSL_ENSURE( meBiff == BIFF4, "WorkbookGlobals::setIsWorkbookFile - invalid call" );
442     mbWorkbook = true;
443 }
444 
445 void WorkbookGlobals::createBuffersPerSheet( sal_Int16 nSheet )
446 {
447     switch( meBiff )
448     {
449         case BIFF2:
450         case BIFF3:
451             OSL_ENSURE( nSheet == 0, "WorkbookGlobals::createBuffersPerSheet - unexpected sheet index" );
452             mxDefNames->setLocalCalcSheet( nSheet );
453         break;
454 
455         case BIFF4:
456             OSL_ENSURE( mbWorkbook || (nSheet == 0), "WorkbookGlobals::createBuffersPerSheet - unexpected sheet index" );
457             // #i11183# sheets in BIFF4W files have own styles and names
458             if( nSheet > 0 )
459             {
460                 mxStyles.reset( new StylesBuffer( *this ) );
461                 mxDefNames.reset( new DefinedNamesBuffer( *this ) );
462                 mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
463             }
464             mxDefNames->setLocalCalcSheet( nSheet );
465         break;
466 
467         case BIFF5:
468             // BIFF5 stores external references per sheet
469             if( nSheet > 0 )
470                 mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
471         break;
472 
473         case BIFF8:
474         break;
475 
476         case BIFF_UNKNOWN:
477         break;
478     }
479 }
480 
481 // private --------------------------------------------------------------------
482 
483 void WorkbookGlobals::initialize( bool bWorkbookFile )
484 {
485     maCellStyles = CREATE_OUSTRING( "CellStyles" );
486     maPageStyles = CREATE_OUSTRING( "PageStyles" );
487     maCellStyleServ = CREATE_OUSTRING( "com.sun.star.style.CellStyle" );
488     maPageStyleServ = CREATE_OUSTRING( "com.sun.star.style.PageStyle" );
489     mnCurrSheet = -1;
490     mbWorkbook = bWorkbookFile;
491     meTextEnc = osl_getThreadTextEncoding();
492     mbHasCodePage = false;
493 
494     // the spreadsheet document
495     mxDoc.set( mrBaseFilter.getModel(), UNO_QUERY );
496     OSL_ENSURE( mxDoc.is(), "WorkbookGlobals::initialize - no spreadsheet document" );
497 
498     mxWorkbookSettings.reset( new WorkbookSettings( *this ) );
499     mxViewSettings.reset( new ViewSettings( *this ) );
500     mxWorksheets.reset( new WorksheetBuffer( *this ) );
501     mxTheme.reset( new ThemeBuffer( *this ) );
502     mxStyles.reset( new StylesBuffer( *this ) );
503     mxSharedStrings.reset( new SharedStringsBuffer( *this ) );
504     mxExtLinks.reset( new ExternalLinkBuffer( *this ) );
505     mxDefNames.reset( new DefinedNamesBuffer( *this ) );
506     mxTables.reset( new TableBuffer( *this ) );
507     mxScenarios.reset( new ScenarioBuffer( *this ) );
508     mxConnections.reset( new ConnectionsBuffer( *this ) );
509     mxPivotCaches.reset( new PivotCacheBuffer( *this ) );
510     mxPivotTables.reset( new PivotTableBuffer( *this ) );
511 
512     mxUnitConverter.reset( new UnitConverter( *this ) );
513     mxAddrConverter.reset( new AddressConverter( *this ) );
514     mxChartConverter.reset( new ExcelChartConverter( *this ) );
515     mxPageSettConverter.reset( new PageSettingsConverter( *this ) );
516 
517     // set some document properties needed during import
518     if( mrBaseFilter.isImportFilter() )
519     {
520         PropertySet aPropSet( mxDoc );
521         // enable editing read-only documents (e.g. from read-only files)
522         aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, true );
523         // #i76026# disable Undo while loading the document
524         aPropSet.setProperty( PROP_IsUndoEnabled, false );
525         // #i79826# disable calculating automatic row height while loading the document
526         aPropSet.setProperty( PROP_IsAdjustHeightEnabled, false );
527         // disable automatic update of linked sheets and DDE links
528         aPropSet.setProperty( PROP_IsExecuteLinkEnabled, false );
529         // #i79890# disable automatic update of defined names
530         Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY );
531         if( xLockable.is() )
532             xLockable->addActionLock();
533 
534         //! TODO: localize progress bar text
535         mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), CREATE_OUSTRING( "Loading..." ) ) );
536         mxFmlaParser.reset( new FormulaParser( *this ) );
537     }
538     else if( mrBaseFilter.isExportFilter() )
539     {
540         //! TODO: localize progress bar text
541         mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), CREATE_OUSTRING( "Saving..." ) ) );
542     }
543 
544     // filter specific
545     switch( getFilterType() )
546     {
547         case FILTER_BIFF:
548             mxCodecHelper.reset( new BiffCodecHelper( *this ) );
549         break;
550 
551         case FILTER_OOXML:
552         break;
553 
554         case FILTER_UNKNOWN:
555         break;
556     }
557 }
558 
559 void WorkbookGlobals::finalize()
560 {
561     // set some document properties needed after import
562     if( mrBaseFilter.isImportFilter() )
563     {
564         PropertySet aPropSet( mxDoc );
565         // #i74668# do not insert default sheets
566         aPropSet.setProperty( PROP_IsLoaded, true );
567         // #i79890# enable automatic update of defined names (before IsAdjustHeightEnabled!)
568         Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY );
569         if( xLockable.is() )
570             xLockable->removeActionLock();
571         // enable automatic update of linked sheets and DDE links
572         aPropSet.setProperty( PROP_IsExecuteLinkEnabled, true );
573         // #i79826# enable updating automatic row height after loading the document
574         aPropSet.setProperty( PROP_IsAdjustHeightEnabled, true );
575         // #i76026# enable Undo after loading the document
576         aPropSet.setProperty( PROP_IsUndoEnabled, true );
577         // disable editing read-only documents (e.g. from read-only files)
578         aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, false );
579         // #111099# open forms in alive mode (has no effect, if no controls in document)
580         aPropSet.setProperty( PROP_ApplyFormDesignMode, false );
581     }
582 }
583 
584 // ============================================================================
585 
586 WorkbookHelper::~WorkbookHelper()
587 {
588 }
589 
590 /*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelFilter& rFilter )
591 {
592     WorkbookGlobalsRef xBookGlob( new WorkbookGlobals( rFilter ) );
593     if( !xBookGlob->isValid() )
594         xBookGlob.reset();
595     return xBookGlob;
596 }
597 
598 /*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelBiffFilter& rFilter, BiffType eBiff )
599 {
600     WorkbookGlobalsRef xBookGlob( new WorkbookGlobals( rFilter, eBiff ) );
601     if( !xBookGlob->isValid() )
602         xBookGlob.reset();
603     return xBookGlob;
604 }
605 
606 // filter ---------------------------------------------------------------------
607 
608 FilterBase& WorkbookHelper::getBaseFilter() const
609 {
610     return mrBookGlob.getBaseFilter();
611 }
612 
613 FilterType WorkbookHelper::getFilterType() const
614 {
615     return mrBookGlob.getFilterType();
616 }
617 
618 SegmentProgressBar& WorkbookHelper::getProgressBar() const
619 {
620     return mrBookGlob.getProgressBar();
621 }
622 
623 bool WorkbookHelper::isWorkbookFile() const
624 {
625     return mrBookGlob.isWorkbookFile();
626 }
627 
628 sal_Int16 WorkbookHelper::getCurrentSheetIndex() const
629 {
630     return mrBookGlob.getCurrentSheetIndex();
631 }
632 
633 void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg )
634 {
635     mrBookGlob.setVbaProjectStorage( rxVbaPrjStrg );
636 }
637 
638 void WorkbookHelper::setCurrentSheetIndex( sal_Int16 nSheet )
639 {
640     mrBookGlob.setCurrentSheetIndex( nSheet );
641 }
642 
643 void WorkbookHelper::finalizeWorkbookImport()
644 {
645     // workbook settings, document and sheet view settings
646     mrBookGlob.getWorkbookSettings().finalizeImport();
647     mrBookGlob.getViewSettings().finalizeImport();
648 
649     /*  Insert all pivot tables. Must be done after loading all sheets, because
650         data pilots expect existing source data on creation. */
651     mrBookGlob.getPivotTables().finalizeImport();
652 
653     /*  Insert scenarios after all sheet processing is done, because new hidden
654         sheets are created for scenarios which would confuse code that relies
655         on certain sheet indexes. Must be done after pivot tables too. */
656     mrBookGlob.getScenarios().finalizeImport();
657 
658     /*  Set 'Default' page style to automatic page numbering (default is manual
659         number 1). Otherwise hidden sheets (e.g. for scenarios) which have
660         'Default' page style will break automatic page numbering for following
661         sheets. Automatic numbering is set by passing the value 0. */
662     PropertySet aDefPageStyle( getStyleObject( CREATE_OUSTRING( "Default" ), true ) );
663     aDefPageStyle.setProperty< sal_Int16 >( PROP_FirstPageNumber, 0 );
664 
665     /*  Import the VBA project (after finalizing workbook settings which
666         contains the workbook code name). */
667     StorageRef xVbaPrjStrg = mrBookGlob.getVbaProjectStorage();
668     if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() )
669         getBaseFilter().getVbaProject().importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() );
670 }
671 
672 // document model -------------------------------------------------------------
673 
674 Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const
675 {
676     return mrBookGlob.getDocument();
677 }
678 
679 Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const
680 {
681     Reference< XSpreadsheet > xSheet;
682     try
683     {
684         Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW );
685         xSheet.set( xSheetsIA->getByIndex( nSheet ), UNO_QUERY_THROW );
686     }
687     catch( Exception& )
688     {
689     }
690     return xSheet;
691 }
692 
693 Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( const OUString& rSheet ) const
694 {
695     Reference< XSpreadsheet > xSheet;
696     try
697     {
698         Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW );
699         xSheet.set( xSheetsNA->getByName( rSheet ), UNO_QUERY );
700     }
701     catch( Exception& )
702     {
703     }
704     return xSheet;
705 }
706 
707 Reference< XCell > WorkbookHelper::getCellFromDoc( const CellAddress& rAddress ) const
708 {
709     Reference< XCell > xCell;
710     try
711     {
712         Reference< XSpreadsheet > xSheet( getSheetFromDoc( rAddress.Sheet ), UNO_SET_THROW );
713         xCell = xSheet->getCellByPosition( rAddress.Column, rAddress.Row );
714     }
715     catch( Exception& )
716     {
717     }
718     return xCell;
719 }
720 
721 Reference< XCellRange > WorkbookHelper::getCellRangeFromDoc( const CellRangeAddress& rRange ) const
722 {
723     Reference< XCellRange > xRange;
724     try
725     {
726         Reference< XSpreadsheet > xSheet( getSheetFromDoc( rRange.Sheet ), UNO_SET_THROW );
727         xRange = xSheet->getCellRangeByPosition( rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow );
728     }
729     catch( Exception& )
730     {
731     }
732     return xRange;
733 }
734 
735 Reference< XNameContainer > WorkbookHelper::getStyleFamily( bool bPageStyles ) const
736 {
737     return mrBookGlob.getStyleFamily( bPageStyles );
738 }
739 
740 Reference< XStyle > WorkbookHelper::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const
741 {
742     return mrBookGlob.getStyleObject( rStyleName, bPageStyle );
743 }
744 
745 Reference< XNamedRange > WorkbookHelper::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const
746 {
747     return mrBookGlob.createNamedRangeObject( orName, nNameFlags );
748 }
749 
750 Reference< XDatabaseRange > WorkbookHelper::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const
751 {
752     return mrBookGlob.createDatabaseRangeObject( orName, rRangeAddr );
753 }
754 
755 Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const
756 {
757     return mrBookGlob.createStyleObject( orStyleName, bPageStyle );
758 }
759 
760 // buffers --------------------------------------------------------------------
761 
762 WorkbookSettings& WorkbookHelper::getWorkbookSettings() const
763 {
764     return mrBookGlob.getWorkbookSettings();
765 }
766 
767 ViewSettings& WorkbookHelper::getViewSettings() const
768 {
769     return mrBookGlob.getViewSettings();
770 }
771 
772 WorksheetBuffer& WorkbookHelper::getWorksheets() const
773 {
774     return mrBookGlob.getWorksheets();
775 }
776 
777 ThemeBuffer& WorkbookHelper::getTheme() const
778 {
779     return mrBookGlob.getTheme();
780 }
781 
782 StylesBuffer& WorkbookHelper::getStyles() const
783 {
784     return mrBookGlob.getStyles();
785 }
786 
787 SharedStringsBuffer& WorkbookHelper::getSharedStrings() const
788 {
789     return mrBookGlob.getSharedStrings();
790 }
791 
792 ExternalLinkBuffer& WorkbookHelper::getExternalLinks() const
793 {
794     return mrBookGlob.getExternalLinks();
795 }
796 
797 DefinedNamesBuffer& WorkbookHelper::getDefinedNames() const
798 {
799     return mrBookGlob.getDefinedNames();
800 }
801 
802 TableBuffer& WorkbookHelper::getTables() const
803 {
804     return mrBookGlob.getTables();
805 }
806 
807 ScenarioBuffer& WorkbookHelper::getScenarios() const
808 {
809     return mrBookGlob.getScenarios();
810 }
811 
812 ConnectionsBuffer& WorkbookHelper::getConnections() const
813 {
814     return mrBookGlob.getConnections();
815 }
816 
817 PivotCacheBuffer& WorkbookHelper::getPivotCaches() const
818 {
819     return mrBookGlob.getPivotCaches();
820 }
821 
822 PivotTableBuffer& WorkbookHelper::getPivotTables() const
823 {
824     return mrBookGlob.getPivotTables();
825 }
826 
827 // converters -----------------------------------------------------------------
828 
829 FormulaParser& WorkbookHelper::getFormulaParser() const
830 {
831     return mrBookGlob.getFormulaParser();
832 }
833 
834 UnitConverter& WorkbookHelper::getUnitConverter() const
835 {
836     return mrBookGlob.getUnitConverter();
837 }
838 
839 AddressConverter& WorkbookHelper::getAddressConverter() const
840 {
841     return mrBookGlob.getAddressConverter();
842 }
843 
844 ExcelChartConverter& WorkbookHelper::getChartConverter() const
845 {
846     return mrBookGlob.getChartConverter();
847 }
848 
849 PageSettingsConverter& WorkbookHelper::getPageSettingsConverter() const
850 {
851     return mrBookGlob.getPageSettingsConverter();
852 }
853 
854 // OOXML/BIFF12 specific ------------------------------------------------------
855 
856 XmlFilterBase& WorkbookHelper::getOoxFilter() const
857 {
858     OSL_ENSURE( mrBookGlob.getFilterType() == FILTER_OOXML, "WorkbookHelper::getOoxFilter - invalid call" );
859     return mrBookGlob.getOoxFilter();
860 }
861 
862 bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
863 {
864     return getOoxFilter().importFragment( rxHandler );
865 }
866 
867 // BIFF specific --------------------------------------------------------------
868 
869 BinaryFilterBase& WorkbookHelper::getBiffFilter() const
870 {
871     OSL_ENSURE( mrBookGlob.getFilterType() == FILTER_BIFF, "WorkbookHelper::getBiffFilter - invalid call" );
872     return mrBookGlob.getBiffFilter();
873 }
874 
875 BiffType WorkbookHelper::getBiff() const
876 {
877     return mrBookGlob.getBiff();
878 }
879 
880 rtl_TextEncoding WorkbookHelper::getTextEncoding() const
881 {
882     return mrBookGlob.getTextEncoding();
883 }
884 
885 void WorkbookHelper::setTextEncoding( rtl_TextEncoding eTextEnc )
886 {
887     mrBookGlob.setTextEncoding( eTextEnc );
888 }
889 
890 void WorkbookHelper::setCodePage( sal_uInt16 nCodePage )
891 {
892     mrBookGlob.setCodePage( nCodePage );
893 }
894 
895 void WorkbookHelper::setAppFontEncoding( rtl_TextEncoding eAppFontEnc )
896 {
897     mrBookGlob.setAppFontEncoding( eAppFontEnc );
898 }
899 
900 void WorkbookHelper::setIsWorkbookFile()
901 {
902     mrBookGlob.setIsWorkbookFile();
903 }
904 
905 void WorkbookHelper::createBuffersPerSheet( sal_Int16 nSheet )
906 {
907     mrBookGlob.createBuffersPerSheet( nSheet );
908 }
909 
910 BiffCodecHelper& WorkbookHelper::getCodecHelper() const
911 {
912     return mrBookGlob.getCodecHelper();
913 }
914 
915 // ============================================================================
916 
917 } // namespace xls
918 } // namespace oox
919