blob: d234e572c3038331d5f2ed281a49aa6512767fb1 [file] [log] [blame]
/**************************************************************
*
* 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