diff options
Diffstat (limited to 'oox/source/xls/workbookhelper.cxx')
-rw-r--r-- | oox/source/xls/workbookhelper.cxx | 980 |
1 files changed, 980 insertions, 0 deletions
diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx new file mode 100644 index 000000000000..b7533d3f7a2e --- /dev/null +++ b/oox/source/xls/workbookhelper.cxx @@ -0,0 +1,980 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/xls/workbookhelper.hxx" + +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/document/XActionLockable.hpp> +#include <com/sun/star/sheet/XDatabaseRange.hpp> +#include <com/sun/star/sheet/XDatabaseRanges.hpp> +#include <com/sun/star/sheet/XUnnamedDatabaseRanges.hpp> +#include <com/sun/star/sheet/XNamedRange.hpp> +#include <com/sun/star/sheet/XNamedRanges.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <osl/thread.h> +#include "oox/drawingml/theme.hxx" +#include "oox/helper/progressbar.hxx" +#include "oox/helper/propertyset.hxx" +#include "oox/ole/vbaproject.hxx" +#include "oox/xls/addressconverter.hxx" +#include "oox/xls/biffinputstream.hxx" +#include "oox/xls/biffcodec.hxx" +#include "oox/xls/connectionsbuffer.hxx" +#include "oox/xls/defnamesbuffer.hxx" +#include "oox/xls/excelchartconverter.hxx" +#include "oox/xls/excelfilter.hxx" +#include "oox/xls/externallinkbuffer.hxx" +#include "oox/xls/formulaparser.hxx" +#include "oox/xls/pagesettings.hxx" +#include "oox/xls/pivotcachebuffer.hxx" +#include "oox/xls/pivottablebuffer.hxx" +#include "oox/xls/scenariobuffer.hxx" +#include "oox/xls/sharedstringsbuffer.hxx" +#include "oox/xls/stylesbuffer.hxx" +#include "oox/xls/tablebuffer.hxx" +#include "oox/xls/themebuffer.hxx" +#include "oox/xls/unitconverter.hxx" +#include "oox/xls/viewsettings.hxx" +#include "oox/xls/workbooksettings.hxx" +#include "oox/xls/worksheetbuffer.hxx" + +namespace oox { +namespace xls { + +// ============================================================================ + +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::sheet; +using namespace ::com::sun::star::style; +using namespace ::com::sun::star::table; +using namespace ::com::sun::star::uno; + +using ::oox::core::BinaryFilterBase; +using ::oox::core::FilterBase; +using ::oox::core::FragmentHandler; +using ::oox::core::XmlFilterBase; +using ::oox::drawingml::Theme; +using ::rtl::OUString; + +// ============================================================================ + +bool IgnoreCaseCompare::operator()( const OUString& rName1, const OUString& rName2 ) const +{ + // there is no wrapper in rtl::OUString, TODO: compare with collator + return ::rtl_ustr_compareIgnoreAsciiCase_WithLength( + rName1.getStr(), rName1.getLength(), rName2.getStr(), rName2.getLength() ) < 0; +} + +// ============================================================================ + +class WorkbookData +{ +public: + explicit WorkbookData( ExcelFilter& rFilter ); + explicit WorkbookData( ExcelBiffFilter& rFilter, BiffType eBiff ); + ~WorkbookData(); + + /** Returns true, if this helper refers to a valid document. */ + inline bool isValid() const { return mxDoc.is(); } + + // filter ----------------------------------------------------------------- + + /** Returns the base filter object (base class of all filters). */ + inline FilterBase& getBaseFilter() const { return mrBaseFilter; } + /** Returns the filter progress bar. */ + inline SegmentProgressBar& getProgressBar() const { return *mxProgressBar; } + /** Returns the file type of the current filter. */ + inline FilterType getFilterType() const { return meFilterType; } + /** Returns true, if the file is a multi-sheet document, or false if single-sheet. */ + inline bool isWorkbookFile() const { return mbWorkbook; } + /** Returns the index of the current sheet in the Calc document. */ + inline sal_Int16 getCurrentSheetIndex() const { return mnCurrSheet; } + /** Sets the index of the current sheet in the Calc document. */ + inline void setCurrentSheetIndex( sal_Int16 nSheet ) { mnCurrSheet = nSheet; } + /** Returns the VBA project storage. */ + inline StorageRef getVbaProjectStorage() const { return mxVbaPrjStrg; } + /** Sets the VBA project storage. */ + inline void setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { mxVbaPrjStrg = rxVbaPrjStrg; } + + // document model --------------------------------------------------------- + + /** Returns a reference to the source/target spreadsheet document model. */ + inline Reference< XSpreadsheetDocument > getDocument() const { return mxDoc; } + /** Returns the cell or page styles container from the Calc document. */ + Reference< XNameContainer > getStyleFamily( bool bPageStyles ) const; + /** Returns the specified cell or page style from the Calc document. */ + Reference< XStyle > getStyleObject( const OUString& rStyleName, bool bPageStyle ) const; + /** Creates and returns a defined name on-the-fly in the Calc document. */ + Reference< XNamedRange > createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const; + /** Creates and returns a database range on-the-fly in the Calc document. */ + Reference< XDatabaseRange > createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const; + /** Creates and returns an unnamed database range on-the-fly in the Calc document. */ + Reference< XDatabaseRange > createUnnamedDatabaseRangeObject( const CellRangeAddress& rRangeAddr ) const; + /** Creates and returns a com.sun.star.style.Style object for cells or pages. */ + Reference< XStyle > createStyleObject( OUString& orStyleName, bool bPageStyle ) const; + + // buffers ---------------------------------------------------------------- + + /** Returns the global workbook settings object. */ + inline WorkbookSettings& getWorkbookSettings() const { return *mxWorkbookSettings; } + /** Returns the workbook and sheet view settings object. */ + inline ViewSettings& getViewSettings() const { return *mxViewSettings; } + /** Returns the worksheet buffer containing sheet names and properties. */ + inline WorksheetBuffer& getWorksheets() const { return *mxWorksheets; } + /** Returns the office theme object read from the theme substorage. */ + inline ThemeBuffer& getTheme() const { return *mxTheme; } + /** Returns all cell formatting objects read from the styles substream. */ + inline StylesBuffer& getStyles() const { return *mxStyles; } + /** Returns the shared strings read from the shared strings substream. */ + inline SharedStringsBuffer& getSharedStrings() const { return *mxSharedStrings; } + /** Returns the external links read from the external links substream. */ + inline ExternalLinkBuffer& getExternalLinks() const { return *mxExtLinks; } + /** Returns the defined names read from the workbook globals. */ + inline DefinedNamesBuffer& getDefinedNames() const { return *mxDefNames; } + /** Returns the tables collection (equivalent to Calc's database ranges). */ + inline TableBuffer& getTables() const { return *mxTables; } + /** Returns the scenarios collection. */ + inline ScenarioBuffer& getScenarios() const { return *mxScenarios; } + /** Returns the collection of external data connections. */ + inline ConnectionsBuffer& getConnections() const { return *mxConnections; } + /** Returns the collection of pivot caches. */ + inline PivotCacheBuffer& getPivotCaches() const { return *mxPivotCaches; } + /** Returns the collection of pivot tables. */ + inline PivotTableBuffer& getPivotTables() { return *mxPivotTables; } + + // converters ------------------------------------------------------------- + + /** Returns the import formula parser. */ + inline FormulaParser& getFormulaParser() const { return *mxFmlaParser; } + /** Returns the measurement unit converter. */ + inline UnitConverter& getUnitConverter() const { return *mxUnitConverter; } + /** Returns the converter for string to cell address/range conversion. */ + inline AddressConverter& getAddressConverter() const { return *mxAddrConverter; } + /** Returns the chart object converter. */ + inline ExcelChartConverter& getChartConverter() const { return *mxChartConverter; } + /** Returns the page/print settings converter. */ + inline PageSettingsConverter& getPageSettingsConverter() const { return *mxPageSettConverter; } + + // OOXML/BIFF12 specific -------------------------------------------------- + + /** Returns the base OOXML/BIFF12 filter object. */ + inline XmlFilterBase& getOoxFilter() const { return *mpOoxFilter; } + + // BIFF2-BIFF8 specific --------------------------------------------------- + + /** Returns the base BIFF filter object. */ + inline BinaryFilterBase& getBiffFilter() const { return *mpBiffFilter; } + /** Returns the BIFF type in binary filter. */ + inline BiffType getBiff() const { return meBiff; } + /** Returns the text encoding used to import/export byte strings. */ + inline rtl_TextEncoding getTextEncoding() const { return meTextEnc; } + /** Sets the text encoding to import/export byte strings. */ + void setTextEncoding( rtl_TextEncoding eTextEnc ); + /** Sets code page read from a CODEPAGE record for byte string import. */ + void setCodePage( sal_uInt16 nCodePage ); + /** Sets text encoding from the default application font, if CODEPAGE record is missing. */ + void setAppFontEncoding( rtl_TextEncoding eAppFontEnc ); + /** Enables workbook file mode, used for BIFF4 workspace files. */ + void setIsWorkbookFile(); + /** Recreates global buffers that are used per sheet in specific BIFF versions. */ + void createBuffersPerSheet( sal_Int16 nSheet ); + /** Returns the codec helper that stores the encoder/decoder object. */ + inline BiffCodecHelper& getCodecHelper() { return *mxCodecHelper; } + +private: + /** Initializes some basic members and sets needed document properties. */ + void initialize( bool bWorkbookFile ); + /** Finalizes the filter process (sets some needed document properties). */ + void finalize(); + +private: + typedef ::std::auto_ptr< SegmentProgressBar > ProgressBarPtr; + typedef ::std::auto_ptr< WorkbookSettings > WorkbookSettPtr; + typedef ::std::auto_ptr< ViewSettings > ViewSettingsPtr; + typedef ::std::auto_ptr< WorksheetBuffer > WorksheetBfrPtr; + typedef ::boost::shared_ptr< ThemeBuffer > ThemeBfrRef; + typedef ::std::auto_ptr< StylesBuffer > StylesBfrPtr; + typedef ::std::auto_ptr< SharedStringsBuffer > SharedStrBfrPtr; + typedef ::std::auto_ptr< ExternalLinkBuffer > ExtLinkBfrPtr; + typedef ::std::auto_ptr< DefinedNamesBuffer > DefNamesBfrPtr; + typedef ::std::auto_ptr< TableBuffer > TableBfrPtr; + typedef ::std::auto_ptr< ScenarioBuffer > ScenarioBfrPtr; + typedef ::std::auto_ptr< ConnectionsBuffer > ConnectionsBfrPtr; + typedef ::std::auto_ptr< PivotCacheBuffer > PivotCacheBfrPtr; + typedef ::std::auto_ptr< PivotTableBuffer > PivotTableBfrPtr; + typedef ::std::auto_ptr< FormulaParser > FormulaParserPtr; + typedef ::std::auto_ptr< UnitConverter > UnitConvPtr; + typedef ::std::auto_ptr< AddressConverter > AddressConvPtr; + typedef ::std::auto_ptr< ExcelChartConverter > ExcelChartConvPtr; + typedef ::std::auto_ptr< PageSettingsConverter > PageSettConvPtr; + typedef ::std::auto_ptr< BiffCodecHelper > BiffCodecHelperPtr; + + OUString maCellStyles; /// Style family name for cell styles. + OUString maPageStyles; /// Style family name for page styles. + OUString maCellStyleServ; /// Service name for a cell style. + OUString maPageStyleServ; /// Service name for a page style. + Reference< XSpreadsheetDocument > mxDoc; /// Document model. + FilterBase& mrBaseFilter; /// Base filter object. + ExcelFilterBase& mrExcelBase; /// Base object for registration of this structure. + FilterType meFilterType; /// File type of the filter. + ProgressBarPtr mxProgressBar; /// The progress bar. + StorageRef mxVbaPrjStrg; /// Storage containing the VBA project. + sal_Int16 mnCurrSheet; /// Current sheet index in Calc dcument. + bool mbWorkbook; /// True = multi-sheet file. + + // buffers + WorkbookSettPtr mxWorkbookSettings; /// Global workbook settings. + ViewSettingsPtr mxViewSettings; /// Workbook and sheet view settings. + WorksheetBfrPtr mxWorksheets; /// Sheet info buffer. + ThemeBfrRef mxTheme; /// Formatting theme from theme substream. + StylesBfrPtr mxStyles; /// All cell style objects from styles substream. + SharedStrBfrPtr mxSharedStrings; /// All strings from shared strings substream. + ExtLinkBfrPtr mxExtLinks; /// All external links. + DefNamesBfrPtr mxDefNames; /// All defined names. + TableBfrPtr mxTables; /// All tables (database ranges). + ScenarioBfrPtr mxScenarios; /// All scenarios. + ConnectionsBfrPtr mxConnections; /// All external data connections. + PivotCacheBfrPtr mxPivotCaches; /// All pivot caches in the document. + PivotTableBfrPtr mxPivotTables; /// All pivot tables in the document. + + // converters + FormulaParserPtr mxFmlaParser; /// Import formula parser. + UnitConvPtr mxUnitConverter; /// General unit converter. + AddressConvPtr mxAddrConverter; /// Cell address and cell range address converter. + ExcelChartConvPtr mxChartConverter; /// Chart object converter. + PageSettConvPtr mxPageSettConverter; /// Page/print settings converter. + + // OOXML/BIFF12 specific + XmlFilterBase* mpOoxFilter; /// Base OOXML/BIFF12 filter object. + + // BIFF2-BIFF8 specific + BinaryFilterBase* mpBiffFilter; /// Base BIFF2-BIFF8 filter object. + BiffCodecHelperPtr mxCodecHelper; /// Encoder/decoder helper. + BiffType meBiff; /// BIFF version for BIFF import/export. + rtl_TextEncoding meTextEnc; /// BIFF byte string text encoding. + bool mbHasCodePage; /// True = CODEPAGE record exists in imported stream. +}; + +// ---------------------------------------------------------------------------- + +WorkbookData::WorkbookData( ExcelFilter& rFilter ) : + mrBaseFilter( rFilter ), + mrExcelBase( rFilter ), + meFilterType( FILTER_OOXML ), + mpOoxFilter( &rFilter ), + mpBiffFilter( 0 ), + meBiff( BIFF_UNKNOWN ) +{ + // register at the filter, needed for virtual callbacks (even during construction) + mrExcelBase.registerWorkbookData( *this ); + initialize( true ); +} + +WorkbookData::WorkbookData( ExcelBiffFilter& rFilter, BiffType eBiff ) : + mrBaseFilter( rFilter ), + mrExcelBase( rFilter ), + meFilterType( FILTER_BIFF ), + mpOoxFilter( 0 ), + mpBiffFilter( &rFilter ), + meBiff( eBiff ) +{ + // register at the filter, needed for virtual callbacks (even during construction) + mrExcelBase.registerWorkbookData( *this ); + initialize( eBiff >= BIFF5 ); +} + +WorkbookData::~WorkbookData() +{ + finalize(); + mrExcelBase.unregisterWorkbookData(); +} + +// document model ------------------------------------------------------------- + +Reference< XNameContainer > WorkbookData::getStyleFamily( bool bPageStyles ) const +{ + Reference< XNameContainer > xStylesNC; + try + { + Reference< XStyleFamiliesSupplier > xFamiliesSup( mxDoc, UNO_QUERY_THROW ); + Reference< XNameAccess > xFamiliesNA( xFamiliesSup->getStyleFamilies(), UNO_QUERY_THROW ); + xStylesNC.set( xFamiliesNA->getByName( bPageStyles ? maPageStyles : maCellStyles ), UNO_QUERY ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xStylesNC.is(), "WorkbookData::getStyleFamily - cannot access style family" ); + return xStylesNC; +} + +Reference< XStyle > WorkbookData::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const +{ + Reference< XStyle > xStyle; + try + { + Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW ); + xStyle.set( xStylesNC->getByName( rStyleName ), UNO_QUERY ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xStyle.is(), "WorkbookData::getStyleObject - cannot access style object" ); + return xStyle; +} + +Reference< XNamedRange > WorkbookData::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const +{ + // create the name and insert it into the Calc document + Reference< XNamedRange > xNamedRange; + if( orName.getLength() > 0 ) try + { + // find an unused name + PropertySet aDocProps( mxDoc ); + Reference< XNamedRanges > xNamedRanges( aDocProps.getAnyProperty( PROP_NamedRanges ), UNO_QUERY_THROW ); + Reference< XNameAccess > xNameAccess( xNamedRanges, UNO_QUERY_THROW ); + orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' ); + // create the named range + xNamedRanges->addNewByName( orName, OUString(), CellAddress( 0, 0, 0 ), nNameFlags ); + xNamedRange.set( xNamedRanges->getByName( orName ), UNO_QUERY ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xNamedRange.is(), "WorkbookData::createNamedRangeObject - cannot create defined name" ); + return xNamedRange; +} + +Reference< XDatabaseRange > WorkbookData::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const +{ + // validate cell range + CellRangeAddress aDestRange = rRangeAddr; + bool bValidRange = getAddressConverter().validateCellRange( aDestRange, true, true ); + + // create database range and insert it into the Calc document + Reference< XDatabaseRange > xDatabaseRange; + if( bValidRange && (orName.getLength() > 0) ) try + { + // find an unused name + PropertySet aDocProps( mxDoc ); + Reference< XDatabaseRanges > xDatabaseRanges( aDocProps.getAnyProperty( PROP_DatabaseRanges ), UNO_QUERY_THROW ); + Reference< XNameAccess > xNameAccess( xDatabaseRanges, UNO_QUERY_THROW ); + orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' ); + // create the database range + xDatabaseRanges->addNewByName( orName, aDestRange ); + xDatabaseRange.set( xDatabaseRanges->getByName( orName ), UNO_QUERY ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xDatabaseRange.is(), "WorkbookData::createDatabaseRangeObject - cannot create database range" ); + return xDatabaseRange; +} + +Reference< XDatabaseRange > WorkbookData::createUnnamedDatabaseRangeObject( const CellRangeAddress& rRangeAddr ) const +{ + // validate cell range + CellRangeAddress aDestRange = rRangeAddr; + bool bValidRange = getAddressConverter().validateCellRange( aDestRange, true, true ); + + // create database range and insert it into the Calc document + Reference< XDatabaseRange > xDatabaseRange; + PropertySet aDocProps( mxDoc ); + Reference< XUnnamedDatabaseRanges > xDatabaseRanges( aDocProps.getAnyProperty( PROP_UnnamedDatabaseRanges ), UNO_QUERY_THROW ); + if( bValidRange ) try + { + xDatabaseRanges->setByTable( aDestRange ); + xDatabaseRange.set( xDatabaseRanges->getByTable( aDestRange.Sheet ), UNO_QUERY ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xDatabaseRange.is(), "WorkbookData::createDatabaseRangeObject - cannot create database range" ); + return xDatabaseRange; +} + +Reference< XStyle > WorkbookData::createStyleObject( OUString& orStyleName, bool bPageStyle ) const +{ + Reference< XStyle > xStyle; + try + { + Reference< XNameContainer > xStylesNC( getStyleFamily( bPageStyle ), UNO_SET_THROW ); + xStyle.set( mrBaseFilter.getModelFactory()->createInstance( bPageStyle ? maPageStyleServ : maCellStyleServ ), UNO_QUERY_THROW ); + orStyleName = ContainerHelper::insertByUnusedName( xStylesNC, orStyleName, ' ', Any( xStyle ), false ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xStyle.is(), "WorkbookData::createStyleObject - cannot create style" ); + return xStyle; +} + +// BIFF specific -------------------------------------------------------------- + +void WorkbookData::setTextEncoding( rtl_TextEncoding eTextEnc ) +{ + if( eTextEnc != RTL_TEXTENCODING_DONTKNOW ) + meTextEnc = eTextEnc; +} + +void WorkbookData::setCodePage( sal_uInt16 nCodePage ) +{ + setTextEncoding( BiffHelper::calcTextEncodingFromCodePage( nCodePage ) ); + mbHasCodePage = true; +} + +void WorkbookData::setAppFontEncoding( rtl_TextEncoding eAppFontEnc ) +{ + if( !mbHasCodePage ) + setTextEncoding( eAppFontEnc ); +} + +void WorkbookData::setIsWorkbookFile() +{ + OSL_ENSURE( meBiff == BIFF4, "WorkbookData::setIsWorkbookFile - invalid call" ); + mbWorkbook = true; +} + +void WorkbookData::createBuffersPerSheet( sal_Int16 nSheet ) +{ + // set mnCurrSheet to enable usage of WorkbookHelper::getCurrentSheetIndex() + mnCurrSheet = nSheet; + switch( meBiff ) + { + case BIFF2: + case BIFF3: + OSL_ENSURE( mnCurrSheet == 0, "WorkbookData::createBuffersPerSheet - unexpected sheet index" ); + mxDefNames->setLocalCalcSheet( mnCurrSheet ); + break; + + case BIFF4: + OSL_ENSURE( mbWorkbook || (mnCurrSheet == 0), "WorkbookData::createBuffersPerSheet - unexpected sheet index" ); + // #i11183# sheets in BIFF4W files have own styles and names + if( mbWorkbook && (mnCurrSheet > 0) ) + { + mxStyles.reset( new StylesBuffer( *this ) ); + mxDefNames.reset( new DefinedNamesBuffer( *this ) ); + mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); + } + mxDefNames->setLocalCalcSheet( mnCurrSheet ); + break; + + case BIFF5: + // BIFF5 stores external references per sheet + mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); + break; + + case BIFF8: + break; + + case BIFF_UNKNOWN: + break; + } + mnCurrSheet = -1; +} + +// private -------------------------------------------------------------------- + +void WorkbookData::initialize( bool bWorkbookFile ) +{ + maCellStyles = CREATE_OUSTRING( "CellStyles" ); + maPageStyles = CREATE_OUSTRING( "PageStyles" ); + maCellStyleServ = CREATE_OUSTRING( "com.sun.star.style.CellStyle" ); + maPageStyleServ = CREATE_OUSTRING( "com.sun.star.style.PageStyle" ); + mnCurrSheet = -1; + mbWorkbook = bWorkbookFile; + meTextEnc = osl_getThreadTextEncoding(); + mbHasCodePage = false; + + // the spreadsheet document + mxDoc.set( mrBaseFilter.getModel(), UNO_QUERY ); + OSL_ENSURE( mxDoc.is(), "WorkbookData::initialize - no spreadsheet document" ); + + mxWorkbookSettings.reset( new WorkbookSettings( *this ) ); + mxViewSettings.reset( new ViewSettings( *this ) ); + mxWorksheets.reset( new WorksheetBuffer( *this ) ); + mxTheme.reset( new ThemeBuffer( *this ) ); + mxStyles.reset( new StylesBuffer( *this ) ); + mxSharedStrings.reset( new SharedStringsBuffer( *this ) ); + mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); + mxDefNames.reset( new DefinedNamesBuffer( *this ) ); + mxTables.reset( new TableBuffer( *this ) ); + mxScenarios.reset( new ScenarioBuffer( *this ) ); + mxConnections.reset( new ConnectionsBuffer( *this ) ); + mxPivotCaches.reset( new PivotCacheBuffer( *this ) ); + mxPivotTables.reset( new PivotTableBuffer( *this ) ); + + mxUnitConverter.reset( new UnitConverter( *this ) ); + mxAddrConverter.reset( new AddressConverter( *this ) ); + mxChartConverter.reset( new ExcelChartConverter( *this ) ); + mxPageSettConverter.reset( new PageSettingsConverter( *this ) ); + + // set some document properties needed during import + if( mrBaseFilter.isImportFilter() ) + { + PropertySet aPropSet( mxDoc ); + // enable editing read-only documents (e.g. from read-only files) + aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, true ); + // #i76026# disable Undo while loading the document + aPropSet.setProperty( PROP_IsUndoEnabled, false ); + // #i79826# disable calculating automatic row height while loading the document + aPropSet.setProperty( PROP_IsAdjustHeightEnabled, false ); + // disable automatic update of linked sheets and DDE links + aPropSet.setProperty( PROP_IsExecuteLinkEnabled, false ); + // #i79890# disable automatic update of defined names + Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY ); + if( xLockable.is() ) + xLockable->addActionLock(); + + //! TODO: localize progress bar text + mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), CREATE_OUSTRING( "Loading..." ) ) ); + mxFmlaParser.reset( new FormulaParser( *this ) ); + } + else if( mrBaseFilter.isExportFilter() ) + { + //! TODO: localize progress bar text + mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), CREATE_OUSTRING( "Saving..." ) ) ); + } + + // filter specific + switch( getFilterType() ) + { + case FILTER_BIFF: + mxCodecHelper.reset( new BiffCodecHelper( *this ) ); + break; + + case FILTER_OOXML: + break; + + case FILTER_UNKNOWN: + break; + } +} + +void WorkbookData::finalize() +{ + // set some document properties needed after import + if( mrBaseFilter.isImportFilter() ) + { + PropertySet aPropSet( mxDoc ); + // #i74668# do not insert default sheets + aPropSet.setProperty( PROP_IsLoaded, true ); + // #i79890# enable automatic update of defined names (before IsAdjustHeightEnabled!) + Reference< XActionLockable > xLockable( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY ); + if( xLockable.is() ) + xLockable->removeActionLock(); + // enable automatic update of linked sheets and DDE links + aPropSet.setProperty( PROP_IsExecuteLinkEnabled, true ); + // #i79826# enable updating automatic row height after loading the document + aPropSet.setProperty( PROP_IsAdjustHeightEnabled, true ); + // #i76026# enable Undo after loading the document + aPropSet.setProperty( PROP_IsUndoEnabled, true ); + // disable editing read-only documents (e.g. from read-only files) + aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, false ); + // #111099# open forms in alive mode (has no effect, if no controls in document) + aPropSet.setProperty( PROP_ApplyFormDesignMode, false ); + } +} + +// ============================================================================ + +WorkbookHelper::~WorkbookHelper() +{ +} + +// filter --------------------------------------------------------------------- + +FilterBase& WorkbookHelper::getBaseFilter() const +{ + return mrBookData.getBaseFilter(); +} + +Reference< XMultiServiceFactory > WorkbookHelper::getGlobalFactory() const +{ + return mrBookData.getBaseFilter().getServiceFactory(); +} + +FilterType WorkbookHelper::getFilterType() const +{ + return mrBookData.getFilterType(); +} + +SegmentProgressBar& WorkbookHelper::getProgressBar() const +{ + return mrBookData.getProgressBar(); +} + +bool WorkbookHelper::isWorkbookFile() const +{ + return mrBookData.isWorkbookFile(); +} + +sal_Int16 WorkbookHelper::getCurrentSheetIndex() const +{ + return mrBookData.getCurrentSheetIndex(); +} + +void WorkbookHelper::setCurrentSheetIndex( sal_Int16 nSheet ) +{ + mrBookData.setCurrentSheetIndex( nSheet ); +} + +void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) +{ + mrBookData.setVbaProjectStorage( rxVbaPrjStrg ); +} + +void WorkbookHelper::finalizeWorkbookImport() +{ + // workbook settings, document and sheet view settings + mrBookData.getWorkbookSettings().finalizeImport(); + mrBookData.getViewSettings().finalizeImport(); + + /* Insert all pivot tables. Must be done after loading all sheets, because + data pilots expect existing source data on creation. */ + mrBookData.getPivotTables().finalizeImport(); + + /* Insert scenarios after all sheet processing is done, because new hidden + sheets are created for scenarios which would confuse code that relies + on certain sheet indexes. Must be done after pivot tables too. */ + mrBookData.getScenarios().finalizeImport(); + + /* Set 'Default' page style to automatic page numbering (default is manual + number 1). Otherwise hidden sheets (e.g. for scenarios) which have + 'Default' page style will break automatic page numbering for following + sheets. Automatic numbering is set by passing the value 0. */ + PropertySet aDefPageStyle( getStyleObject( CREATE_OUSTRING( "Default" ), true ) ); + aDefPageStyle.setProperty< sal_Int16 >( PROP_FirstPageNumber, 0 ); + + /* Import the VBA project (after finalizing workbook settings which + contains the workbook code name). */ + StorageRef xVbaPrjStrg = mrBookData.getVbaProjectStorage(); + if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() ) + getBaseFilter().getVbaProject().importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() ); +} + +// document model ------------------------------------------------------------- + +Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const +{ + return mrBookData.getDocument(); +} + +Reference< XMultiServiceFactory > WorkbookHelper::getDocumentFactory() const +{ + return mrBookData.getBaseFilter().getModelFactory(); +} + +Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const +{ + Reference< XSpreadsheet > xSheet; + try + { + Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW ); + xSheet.set( xSheetsIA->getByIndex( nSheet ), UNO_QUERY_THROW ); + } + catch( Exception& ) + { + } + return xSheet; +} + +Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( const OUString& rSheet ) const +{ + Reference< XSpreadsheet > xSheet; + try + { + Reference< XNameAccess > xSheetsNA( getDocument()->getSheets(), UNO_QUERY_THROW ); + xSheet.set( xSheetsNA->getByName( rSheet ), UNO_QUERY ); + } + catch( Exception& ) + { + } + return xSheet; +} + +Reference< XCell > WorkbookHelper::getCellFromDoc( const CellAddress& rAddress ) const +{ + Reference< XCell > xCell; + try + { + Reference< XSpreadsheet > xSheet( getSheetFromDoc( rAddress.Sheet ), UNO_SET_THROW ); + xCell = xSheet->getCellByPosition( rAddress.Column, rAddress.Row ); + } + catch( Exception& ) + { + } + return xCell; +} + +Reference< XCellRange > WorkbookHelper::getCellRangeFromDoc( const CellRangeAddress& rRange ) const +{ + Reference< XCellRange > xRange; + try + { + Reference< XSpreadsheet > xSheet( getSheetFromDoc( rRange.Sheet ), UNO_SET_THROW ); + xRange = xSheet->getCellRangeByPosition( rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow ); + } + catch( Exception& ) + { + } + return xRange; +} + +Reference< XNameContainer > WorkbookHelper::getStyleFamily( bool bPageStyles ) const +{ + return mrBookData.getStyleFamily( bPageStyles ); +} + +Reference< XStyle > WorkbookHelper::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const +{ + return mrBookData.getStyleObject( rStyleName, bPageStyle ); +} + +Reference< XNamedRange > WorkbookHelper::createNamedRangeObject( OUString& orName, sal_Int32 nNameFlags ) const +{ + return mrBookData.createNamedRangeObject( orName, nNameFlags ); +} + +Reference< XDatabaseRange > WorkbookHelper::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const +{ + return mrBookData.createDatabaseRangeObject( orName, rRangeAddr ); +} + +Reference< XDatabaseRange > WorkbookHelper::createUnnamedDatabaseRangeObject( const CellRangeAddress& rRangeAddr ) const +{ + return mrBookData.createUnnamedDatabaseRangeObject( rRangeAddr ); +} + +Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const +{ + return mrBookData.createStyleObject( orStyleName, bPageStyle ); +} + +// buffers -------------------------------------------------------------------- + +WorkbookSettings& WorkbookHelper::getWorkbookSettings() const +{ + return mrBookData.getWorkbookSettings(); +} + +ViewSettings& WorkbookHelper::getViewSettings() const +{ + return mrBookData.getViewSettings(); +} + +WorksheetBuffer& WorkbookHelper::getWorksheets() const +{ + return mrBookData.getWorksheets(); +} + +ThemeBuffer& WorkbookHelper::getTheme() const +{ + return mrBookData.getTheme(); +} + +StylesBuffer& WorkbookHelper::getStyles() const +{ + return mrBookData.getStyles(); +} + +SharedStringsBuffer& WorkbookHelper::getSharedStrings() const +{ + return mrBookData.getSharedStrings(); +} + +ExternalLinkBuffer& WorkbookHelper::getExternalLinks() const +{ + return mrBookData.getExternalLinks(); +} + +DefinedNamesBuffer& WorkbookHelper::getDefinedNames() const +{ + return mrBookData.getDefinedNames(); +} + +TableBuffer& WorkbookHelper::getTables() const +{ + return mrBookData.getTables(); +} + +ScenarioBuffer& WorkbookHelper::getScenarios() const +{ + return mrBookData.getScenarios(); +} + +ConnectionsBuffer& WorkbookHelper::getConnections() const +{ + return mrBookData.getConnections(); +} + +PivotCacheBuffer& WorkbookHelper::getPivotCaches() const +{ + return mrBookData.getPivotCaches(); +} + +PivotTableBuffer& WorkbookHelper::getPivotTables() const +{ + return mrBookData.getPivotTables(); +} + +// converters ----------------------------------------------------------------- + +FormulaParser& WorkbookHelper::getFormulaParser() const +{ + return mrBookData.getFormulaParser(); +} + +UnitConverter& WorkbookHelper::getUnitConverter() const +{ + return mrBookData.getUnitConverter(); +} + +AddressConverter& WorkbookHelper::getAddressConverter() const +{ + return mrBookData.getAddressConverter(); +} + +ExcelChartConverter& WorkbookHelper::getChartConverter() const +{ + return mrBookData.getChartConverter(); +} + +PageSettingsConverter& WorkbookHelper::getPageSettingsConverter() const +{ + return mrBookData.getPageSettingsConverter(); +} + +// OOXML/BIFF12 specific ------------------------------------------------------ + +XmlFilterBase& WorkbookHelper::getOoxFilter() const +{ + OSL_ENSURE( mrBookData.getFilterType() == FILTER_OOXML, "WorkbookHelper::getOoxFilter - invalid call" ); + return mrBookData.getOoxFilter(); +} + +bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler >& rxHandler ) +{ + return getOoxFilter().importFragment( rxHandler ); +} + +// BIFF specific -------------------------------------------------------------- + +BinaryFilterBase& WorkbookHelper::getBiffFilter() const +{ + OSL_ENSURE( mrBookData.getFilterType() == FILTER_BIFF, "WorkbookHelper::getBiffFilter - invalid call" ); + return mrBookData.getBiffFilter(); +} + +BiffType WorkbookHelper::getBiff() const +{ + return mrBookData.getBiff(); +} + +rtl_TextEncoding WorkbookHelper::getTextEncoding() const +{ + return mrBookData.getTextEncoding(); +} + +void WorkbookHelper::setTextEncoding( rtl_TextEncoding eTextEnc ) +{ + mrBookData.setTextEncoding( eTextEnc ); +} + +void WorkbookHelper::setCodePage( sal_uInt16 nCodePage ) +{ + mrBookData.setCodePage( nCodePage ); +} + +void WorkbookHelper::setAppFontEncoding( rtl_TextEncoding eAppFontEnc ) +{ + mrBookData.setAppFontEncoding( eAppFontEnc ); +} + +void WorkbookHelper::setIsWorkbookFile() +{ + mrBookData.setIsWorkbookFile(); +} + +void WorkbookHelper::createBuffersPerSheet( sal_Int16 nSheet ) +{ + mrBookData.createBuffersPerSheet( nSheet ); +} + +BiffCodecHelper& WorkbookHelper::getCodecHelper() const +{ + return mrBookData.getCodecHelper(); +} + +// ============================================================================ + +namespace prv { + +WorkbookDataOwner::WorkbookDataOwner( WorkbookDataRef xBookData ) : + mxBookData( xBookData ) +{ +} + +WorkbookDataOwner::~WorkbookDataOwner() +{ +} + +} // namespace prv + +// ---------------------------------------------------------------------------- + +WorkbookHelperRoot::WorkbookHelperRoot( ExcelFilter& rFilter ) : + prv::WorkbookDataOwner( prv::WorkbookDataRef( new WorkbookData( rFilter ) ) ), + WorkbookHelper( *mxBookData ) +{ +} + +WorkbookHelperRoot::WorkbookHelperRoot( ExcelBiffFilter& rFilter, BiffType eBiff ) : + prv::WorkbookDataOwner( prv::WorkbookDataRef( new WorkbookData( rFilter, eBiff ) ) ), + WorkbookHelper( *mxBookData ) +{ +} + +bool WorkbookHelperRoot::isValid() const +{ + return mxBookData->isValid(); +} + +// ============================================================================ + +} // namespace xls +} // namespace oox + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |