| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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/XNamedRange2.hpp> |
| #include <com/sun/star/sheet/XNamedRanges2.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 WorkbookGlobals |
| { |
| public: |
| explicit WorkbookGlobals( ExcelFilter& rFilter ); |
| explicit WorkbookGlobals( ExcelBiffFilter& rFilter, BiffType eBiff ); |
| ~WorkbookGlobals(); |
| |
| /** 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 VBA project storage. */ |
| inline StorageRef getVbaProjectStorage() const { return mxVbaPrjStrg; } |
| /** Returns the index of the current Calc sheet, if filter currently processes a sheet. */ |
| inline sal_Int16 getCurrentSheetIndex() const { return mnCurrSheet; } |
| |
| /** Sets the VBA project storage used to import VBA source code and forms. */ |
| inline void setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) { mxVbaPrjStrg = rxVbaPrjStrg; } |
| /** Sets the index of the current Calc sheet, if filter currently processes a sheet. */ |
| inline void setCurrentSheetIndex( sal_Int16 nSheet ) { mnCurrSheet = nSheet; } |
| |
| // 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< XNamedRange2 > createNamedRangeObject( OUString& orScope, 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 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. |
| }; |
| |
| // ---------------------------------------------------------------------------- |
| |
| WorkbookGlobals::WorkbookGlobals( 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.registerWorkbookGlobals( *this ); |
| initialize( true ); |
| } |
| |
| WorkbookGlobals::WorkbookGlobals( 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.registerWorkbookGlobals( *this ); |
| initialize( eBiff >= BIFF5 ); |
| } |
| |
| WorkbookGlobals::~WorkbookGlobals() |
| { |
| finalize(); |
| mrExcelBase.unregisterWorkbookGlobals(); |
| } |
| |
| // document model ------------------------------------------------------------- |
| |
| Reference< XNameContainer > WorkbookGlobals::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(), "WorkbookGlobals::getStyleFamily - cannot access style family" ); |
| return xStylesNC; |
| } |
| |
| Reference< XStyle > WorkbookGlobals::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(), "WorkbookGlobals::getStyleObject - cannot access style object" ); |
| return xStyle; |
| } |
| |
| Reference< XNamedRange2 > WorkbookGlobals::createNamedRangeObject( OUString& orScope, OUString& orName, sal_Int32 nNameFlags ) const |
| { |
| // create the name and insert it into the Calc document |
| Reference< XNamedRange2 > xNamedRange; |
| if( orName.getLength() > 0 ) try |
| { |
| // find an unused name |
| PropertySet aDocProps( mxDoc ); |
| Reference< XNamedRanges2 > xNamedRanges( aDocProps.getAnyProperty( PROP_NamedRanges2 ), UNO_QUERY_THROW ); |
| Reference< XNameAccess > xNameAccess( xNamedRanges, UNO_QUERY_THROW ); |
| orName = ContainerHelper::getUnusedName( xNameAccess, orName, '_' ); |
| // create the named range |
| xNamedRanges->addNewByScopeName( orScope, orName, OUString(), CellAddress( 0, 0, 0 ), nNameFlags ); |
| xNamedRange.set( xNamedRanges->getByScopeName( orScope, orName ), UNO_QUERY ); |
| } |
| catch( Exception& ) |
| { |
| } |
| OSL_ENSURE( xNamedRange.is(), "WorkbookGlobals::createNamedRangeObject - cannot create defined name" ); |
| return xNamedRange; |
| } |
| |
| Reference< XDatabaseRange > WorkbookGlobals::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(), "WorkbookGlobals::createDatabaseRangeObject - cannot create database range" ); |
| return xDatabaseRange; |
| } |
| |
| Reference< XStyle > WorkbookGlobals::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(), "WorkbookGlobals::createStyleObject - cannot create style" ); |
| return xStyle; |
| } |
| |
| // BIFF specific -------------------------------------------------------------- |
| |
| void WorkbookGlobals::setTextEncoding( rtl_TextEncoding eTextEnc ) |
| { |
| if( eTextEnc != RTL_TEXTENCODING_DONTKNOW ) |
| meTextEnc = eTextEnc; |
| } |
| |
| void WorkbookGlobals::setCodePage( sal_uInt16 nCodePage ) |
| { |
| setTextEncoding( BiffHelper::calcTextEncodingFromCodePage( nCodePage ) ); |
| mbHasCodePage = true; |
| } |
| |
| void WorkbookGlobals::setAppFontEncoding( rtl_TextEncoding eAppFontEnc ) |
| { |
| if( !mbHasCodePage ) |
| setTextEncoding( eAppFontEnc ); |
| } |
| |
| void WorkbookGlobals::setIsWorkbookFile() |
| { |
| OSL_ENSURE( meBiff == BIFF4, "WorkbookGlobals::setIsWorkbookFile - invalid call" ); |
| mbWorkbook = true; |
| } |
| |
| void WorkbookGlobals::createBuffersPerSheet( sal_Int16 nSheet ) |
| { |
| switch( meBiff ) |
| { |
| case BIFF2: |
| case BIFF3: |
| OSL_ENSURE( nSheet == 0, "WorkbookGlobals::createBuffersPerSheet - unexpected sheet index" ); |
| mxDefNames->setLocalCalcSheet( nSheet ); |
| break; |
| |
| case BIFF4: |
| OSL_ENSURE( mbWorkbook || (nSheet == 0), "WorkbookGlobals::createBuffersPerSheet - unexpected sheet index" ); |
| // #i11183# sheets in BIFF4W files have own styles and names |
| if( nSheet > 0 ) |
| { |
| mxStyles.reset( new StylesBuffer( *this ) ); |
| mxDefNames.reset( new DefinedNamesBuffer( *this ) ); |
| mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); |
| } |
| mxDefNames->setLocalCalcSheet( nSheet ); |
| break; |
| |
| case BIFF5: |
| // BIFF5 stores external references per sheet |
| if( nSheet > 0 ) |
| mxExtLinks.reset( new ExternalLinkBuffer( *this ) ); |
| break; |
| |
| case BIFF8: |
| break; |
| |
| case BIFF_UNKNOWN: |
| break; |
| } |
| } |
| |
| // private -------------------------------------------------------------------- |
| |
| void WorkbookGlobals::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(), "WorkbookGlobals::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 WorkbookGlobals::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() |
| { |
| } |
| |
| /*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelFilter& rFilter ) |
| { |
| WorkbookGlobalsRef xBookGlob( new WorkbookGlobals( rFilter ) ); |
| if( !xBookGlob->isValid() ) |
| xBookGlob.reset(); |
| return xBookGlob; |
| } |
| |
| /*static*/ WorkbookGlobalsRef WorkbookHelper::constructGlobals( ExcelBiffFilter& rFilter, BiffType eBiff ) |
| { |
| WorkbookGlobalsRef xBookGlob( new WorkbookGlobals( rFilter, eBiff ) ); |
| if( !xBookGlob->isValid() ) |
| xBookGlob.reset(); |
| return xBookGlob; |
| } |
| |
| // filter --------------------------------------------------------------------- |
| |
| FilterBase& WorkbookHelper::getBaseFilter() const |
| { |
| return mrBookGlob.getBaseFilter(); |
| } |
| |
| FilterType WorkbookHelper::getFilterType() const |
| { |
| return mrBookGlob.getFilterType(); |
| } |
| |
| SegmentProgressBar& WorkbookHelper::getProgressBar() const |
| { |
| return mrBookGlob.getProgressBar(); |
| } |
| |
| bool WorkbookHelper::isWorkbookFile() const |
| { |
| return mrBookGlob.isWorkbookFile(); |
| } |
| |
| sal_Int16 WorkbookHelper::getCurrentSheetIndex() const |
| { |
| return mrBookGlob.getCurrentSheetIndex(); |
| } |
| |
| void WorkbookHelper::setVbaProjectStorage( const StorageRef& rxVbaPrjStrg ) |
| { |
| mrBookGlob.setVbaProjectStorage( rxVbaPrjStrg ); |
| } |
| |
| void WorkbookHelper::setCurrentSheetIndex( sal_Int16 nSheet ) |
| { |
| mrBookGlob.setCurrentSheetIndex( nSheet ); |
| } |
| |
| void WorkbookHelper::finalizeWorkbookImport() |
| { |
| // workbook settings, document and sheet view settings |
| mrBookGlob.getWorkbookSettings().finalizeImport(); |
| mrBookGlob.getViewSettings().finalizeImport(); |
| |
| /* Insert all pivot tables. Must be done after loading all sheets, because |
| data pilots expect existing source data on creation. */ |
| mrBookGlob.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. */ |
| mrBookGlob.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 = mrBookGlob.getVbaProjectStorage(); |
| if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() ) |
| getBaseFilter().getVbaProject().importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() ); |
| } |
| |
| // document model ------------------------------------------------------------- |
| |
| Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const |
| { |
| return mrBookGlob.getDocument(); |
| } |
| |
| 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 mrBookGlob.getStyleFamily( bPageStyles ); |
| } |
| |
| Reference< XStyle > WorkbookHelper::getStyleObject( const OUString& rStyleName, bool bPageStyle ) const |
| { |
| return mrBookGlob.getStyleObject( rStyleName, bPageStyle ); |
| } |
| |
| Reference< XNamedRange2 > WorkbookHelper::createNamedRangeObject( OUString& orName, sal_Int32 nSheetId, sal_Int32 nNameFlags ) const |
| { |
| OUString orScope = nSheetId >= 0? getWorksheets().getCalcSheetName(nSheetId) : OUString(); |
| return mrBookGlob.createNamedRangeObject( orScope, orName, nNameFlags ); |
| } |
| |
| Reference< XDatabaseRange > WorkbookHelper::createDatabaseRangeObject( OUString& orName, const CellRangeAddress& rRangeAddr ) const |
| { |
| return mrBookGlob.createDatabaseRangeObject( orName, rRangeAddr ); |
| } |
| |
| Reference< XStyle > WorkbookHelper::createStyleObject( OUString& orStyleName, bool bPageStyle ) const |
| { |
| return mrBookGlob.createStyleObject( orStyleName, bPageStyle ); |
| } |
| |
| // buffers -------------------------------------------------------------------- |
| |
| WorkbookSettings& WorkbookHelper::getWorkbookSettings() const |
| { |
| return mrBookGlob.getWorkbookSettings(); |
| } |
| |
| ViewSettings& WorkbookHelper::getViewSettings() const |
| { |
| return mrBookGlob.getViewSettings(); |
| } |
| |
| WorksheetBuffer& WorkbookHelper::getWorksheets() const |
| { |
| return mrBookGlob.getWorksheets(); |
| } |
| |
| ThemeBuffer& WorkbookHelper::getTheme() const |
| { |
| return mrBookGlob.getTheme(); |
| } |
| |
| StylesBuffer& WorkbookHelper::getStyles() const |
| { |
| return mrBookGlob.getStyles(); |
| } |
| |
| SharedStringsBuffer& WorkbookHelper::getSharedStrings() const |
| { |
| return mrBookGlob.getSharedStrings(); |
| } |
| |
| ExternalLinkBuffer& WorkbookHelper::getExternalLinks() const |
| { |
| return mrBookGlob.getExternalLinks(); |
| } |
| |
| DefinedNamesBuffer& WorkbookHelper::getDefinedNames() const |
| { |
| return mrBookGlob.getDefinedNames(); |
| } |
| |
| TableBuffer& WorkbookHelper::getTables() const |
| { |
| return mrBookGlob.getTables(); |
| } |
| |
| ScenarioBuffer& WorkbookHelper::getScenarios() const |
| { |
| return mrBookGlob.getScenarios(); |
| } |
| |
| ConnectionsBuffer& WorkbookHelper::getConnections() const |
| { |
| return mrBookGlob.getConnections(); |
| } |
| |
| PivotCacheBuffer& WorkbookHelper::getPivotCaches() const |
| { |
| return mrBookGlob.getPivotCaches(); |
| } |
| |
| PivotTableBuffer& WorkbookHelper::getPivotTables() const |
| { |
| return mrBookGlob.getPivotTables(); |
| } |
| |
| // converters ----------------------------------------------------------------- |
| |
| FormulaParser& WorkbookHelper::getFormulaParser() const |
| { |
| return mrBookGlob.getFormulaParser(); |
| } |
| |
| UnitConverter& WorkbookHelper::getUnitConverter() const |
| { |
| return mrBookGlob.getUnitConverter(); |
| } |
| |
| AddressConverter& WorkbookHelper::getAddressConverter() const |
| { |
| return mrBookGlob.getAddressConverter(); |
| } |
| |
| ExcelChartConverter& WorkbookHelper::getChartConverter() const |
| { |
| return mrBookGlob.getChartConverter(); |
| } |
| |
| PageSettingsConverter& WorkbookHelper::getPageSettingsConverter() const |
| { |
| return mrBookGlob.getPageSettingsConverter(); |
| } |
| |
| // OOXML/BIFF12 specific ------------------------------------------------------ |
| |
| XmlFilterBase& WorkbookHelper::getOoxFilter() const |
| { |
| OSL_ENSURE( mrBookGlob.getFilterType() == FILTER_OOXML, "WorkbookHelper::getOoxFilter - invalid call" ); |
| return mrBookGlob.getOoxFilter(); |
| } |
| |
| bool WorkbookHelper::importOoxFragment( const ::rtl::Reference< FragmentHandler >& rxHandler ) |
| { |
| return getOoxFilter().importFragment( rxHandler ); |
| } |
| |
| // BIFF specific -------------------------------------------------------------- |
| |
| BinaryFilterBase& WorkbookHelper::getBiffFilter() const |
| { |
| OSL_ENSURE( mrBookGlob.getFilterType() == FILTER_BIFF, "WorkbookHelper::getBiffFilter - invalid call" ); |
| return mrBookGlob.getBiffFilter(); |
| } |
| |
| BiffType WorkbookHelper::getBiff() const |
| { |
| return mrBookGlob.getBiff(); |
| } |
| |
| rtl_TextEncoding WorkbookHelper::getTextEncoding() const |
| { |
| return mrBookGlob.getTextEncoding(); |
| } |
| |
| void WorkbookHelper::setTextEncoding( rtl_TextEncoding eTextEnc ) |
| { |
| mrBookGlob.setTextEncoding( eTextEnc ); |
| } |
| |
| void WorkbookHelper::setCodePage( sal_uInt16 nCodePage ) |
| { |
| mrBookGlob.setCodePage( nCodePage ); |
| } |
| |
| void WorkbookHelper::setAppFontEncoding( rtl_TextEncoding eAppFontEnc ) |
| { |
| mrBookGlob.setAppFontEncoding( eAppFontEnc ); |
| } |
| |
| void WorkbookHelper::setIsWorkbookFile() |
| { |
| mrBookGlob.setIsWorkbookFile(); |
| } |
| |
| void WorkbookHelper::createBuffersPerSheet( sal_Int16 nSheet ) |
| { |
| mrBookGlob.createBuffersPerSheet( nSheet ); |
| } |
| |
| BiffCodecHelper& WorkbookHelper::getCodecHelper() const |
| { |
| return mrBookGlob.getCodecHelper(); |
| } |
| |
| // ============================================================================ |
| |
| } // namespace xls |
| } // namespace oox |