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