diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2010-01-19 23:22:49 +0100 |
---|---|---|
committer | Kohei Yoshida <kyoshida@novell.com> | 2010-01-19 23:22:49 +0100 |
commit | 611da14834d09502cda70a62fe0fe0b25b0c5b70 (patch) | |
tree | 60379cd8df25decf535c38aa32829c502f0fce54 /oox/source/xls | |
parent | 3e5b86777ca46e9dd6574e8c88ef47942da01495 (diff) | |
parent | 61e959dac551c5984e9865edea9f2ad7203233fd (diff) |
rebased to DEV300_m69.
Diffstat (limited to 'oox/source/xls')
-rw-r--r-- | oox/source/xls/excelhandlers.cxx | 129 | ||||
-rw-r--r-- | oox/source/xls/externallinkbuffer.cxx | 22 | ||||
-rw-r--r-- | oox/source/xls/formulabase.cxx | 9 | ||||
-rw-r--r-- | oox/source/xls/pivottablebuffer.cxx | 2 | ||||
-rw-r--r-- | oox/source/xls/stylesbuffer.cxx | 334 | ||||
-rw-r--r-- | oox/source/xls/workbookfragment.cxx | 2 | ||||
-rw-r--r-- | oox/source/xls/workbookhelper.cxx | 9 | ||||
-rw-r--r-- | oox/source/xls/workbooksettings.cxx | 2 | ||||
-rw-r--r-- | oox/source/xls/worksheetbuffer.cxx | 28 | ||||
-rw-r--r-- | oox/source/xls/worksheetfragment.cxx | 18 | ||||
-rw-r--r-- | oox/source/xls/worksheetsettings.cxx | 33 |
11 files changed, 359 insertions, 229 deletions
diff --git a/oox/source/xls/excelhandlers.cxx b/oox/source/xls/excelhandlers.cxx index aa5a8634a60d..fa72d9602fed 100644 --- a/oox/source/xls/excelhandlers.cxx +++ b/oox/source/xls/excelhandlers.cxx @@ -143,68 +143,12 @@ BiffFragmentHandler::BiffFragmentHandler( const BiffFragmentHandler& rHandler ) BiffFragmentType BiffFragmentHandler::startFragment( BiffType eBiff ) { - BiffFragmentType eFragment = BIFF_FRAGMENT_UNKNOWN; - if( mrStrm.startNextRecord() ) - { - /* #i23425# Don't rely on BOF record ID to read BOF contents, but on - the detected BIFF version. */ - if( isBofRecord() ) - { - // BOF is always written unencrypted - mrStrm.enableDecoder( false ); - mrStrm.skip( 2 ); - sal_uInt16 nType = mrStrm.readuInt16(); + return mrStrm.startNextRecord() ? implStartFragment( eBiff ) : BIFF_FRAGMENT_UNKNOWN; +} - // decide which fragment types are valid for current BIFF version - switch( eBiff ) - { - case BIFF2: switch( nType ) - { - case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break; - case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; - // #i51490# Excel interprets invalid types as worksheet - default: eFragment = BIFF_FRAGMENT_WORKSHEET; - } - break; - - case BIFF3: switch( nType ) - { - case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break; - case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; - case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN; break; - // #i51490# Excel interprets invalid types as worksheet - default: eFragment = BIFF_FRAGMENT_WORKSHEET; - }; - break; - - case BIFF4: switch( nType ) - { - case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break; - case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; - case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_WORKSPACE; break; - // #i51490# Excel interprets invalid types as worksheet - default: eFragment = BIFF_FRAGMENT_WORKSHEET; - }; - break; - - case BIFF5: - case BIFF8: switch( nType ) - { - case BIFF_BOF_GLOBALS: eFragment = BIFF_FRAGMENT_GLOBALS; break; - case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_CHARTSHEET; break; - case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; - case BIFF_BOF_MODULE: eFragment = BIFF_FRAGMENT_MODULESHEET; break; - case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN; break; - // #i51490# Excel interprets invalid types as worksheet - default: eFragment = BIFF_FRAGMENT_WORKSHEET; - }; - break; - - case BIFF_UNKNOWN: break; - } - } - } - return eFragment; +BiffFragmentType BiffFragmentHandler::startFragment( BiffType eBiff, sal_Int64 nRecHandle ) +{ + return mrStrm.startRecordByHandle( nRecHandle ) ? implStartFragment( eBiff ) : BIFF_FRAGMENT_UNKNOWN; } bool BiffFragmentHandler::skipFragment() @@ -215,6 +159,69 @@ bool BiffFragmentHandler::skipFragment() return !mrStrm.isEof() && (mrStrm.getRecId() == BIFF_ID_EOF); } +BiffFragmentType BiffFragmentHandler::implStartFragment( BiffType eBiff ) +{ + BiffFragmentType eFragment = BIFF_FRAGMENT_UNKNOWN; + /* #i23425# Don't rely on BOF record ID to read BOF contents, but on + the detected BIFF version. */ + if( isBofRecord() ) + { + // BOF is always written unencrypted + mrStrm.enableDecoder( false ); + mrStrm.skip( 2 ); + sal_uInt16 nType = mrStrm.readuInt16(); + + // decide which fragment types are valid for current BIFF version + switch( eBiff ) + { + case BIFF2: switch( nType ) + { + case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break; + case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; + // #i51490# Excel interprets invalid types as worksheet + default: eFragment = BIFF_FRAGMENT_WORKSHEET; + } + break; + + case BIFF3: switch( nType ) + { + case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break; + case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; + case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN; break; + // #i51490# Excel interprets invalid types as worksheet + default: eFragment = BIFF_FRAGMENT_WORKSHEET; + }; + break; + + case BIFF4: switch( nType ) + { + case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_EMPTYSHEET; break; + case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; + case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_WORKSPACE; break; + // #i51490# Excel interprets invalid types as worksheet + default: eFragment = BIFF_FRAGMENT_WORKSHEET; + }; + break; + + case BIFF5: + case BIFF8: switch( nType ) + { + case BIFF_BOF_GLOBALS: eFragment = BIFF_FRAGMENT_GLOBALS; break; + case BIFF_BOF_CHART: eFragment = BIFF_FRAGMENT_CHARTSHEET; break; + case BIFF_BOF_MACRO: eFragment = BIFF_FRAGMENT_MACROSHEET; break; + case BIFF_BOF_MODULE: eFragment = BIFF_FRAGMENT_MODULESHEET; break; + case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN; break; + // #i51490# Excel interprets invalid types as worksheet + default: eFragment = BIFF_FRAGMENT_WORKSHEET; + }; + break; + + case BIFF_UNKNOWN: break; + } + } + return eFragment; +} + // ============================================================================ BiffWorkbookFragmentBase::BiffWorkbookFragmentBase( const WorkbookHelper& rHelper, const OUString& rStrmName, bool bCloneDecoder ) : diff --git a/oox/source/xls/externallinkbuffer.cxx b/oox/source/xls/externallinkbuffer.cxx index 26a1df09cc69..c75625216142 100644 --- a/oox/source/xls/externallinkbuffer.cxx +++ b/oox/source/xls/externallinkbuffer.cxx @@ -1030,18 +1030,20 @@ void ExternalLinkBuffer::importExternalName( BiffInputStream& rStrm ) void ExternalLinkBuffer::importExternSheet8( BiffInputStream& rStrm ) { - OSL_ENSURE( getBiff() == BIFF8, "ExternalLinkBuffer::importExternSheet - wrong BIFF version" ); - OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternSheet - multiple EXTERNSHEET records" ); - maRefSheets.clear(); + OSL_ENSURE( getBiff() == BIFF8, "ExternalLinkBuffer::importExternSheet8 - wrong BIFF version" ); + sal_uInt16 nRefCount; rStrm >> nRefCount; - maRefSheets.reserve( nRefCount ); - for( sal_uInt16 nRefId = 0; !rStrm.isEof() && (nRefId < nRefCount); ++nRefId ) - { - RefSheetsModel aRefSheets; - aRefSheets.readBiff8Data( rStrm ); - maRefSheets.push_back( aRefSheets ); - } + OSL_ENSURE( static_cast< sal_Int64 >( nRefCount * 6 ) == rStrm.getRemaining(), "ExternalLinkBuffer::importExternSheet8 - invalid count" ); + nRefCount = static_cast< sal_uInt16 >( ::std::min< sal_Int64 >( nRefCount, rStrm.getRemaining() / 6 ) ); + + /* #i104057# A weird external XLS generator writes multiple EXTERNSHEET + records instead of only one as expected. Surprisingly, Excel seems to + insert the entries of the second record before the entries of the first + record. */ + maRefSheets.insert( maRefSheets.begin(), nRefCount, RefSheetsModel() ); + for( RefSheetsModelVec::iterator aIt = maRefSheets.begin(); !rStrm.isEof() && (nRefCount > 0); --nRefCount ) + aIt->readBiff8Data( rStrm ); } Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index 5240960f7a88..67c595d2b9f0 100644 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -1655,13 +1655,16 @@ void FormulaProcessorBase::extractCellRangeList( ApiCellRangeList& orRanges, sal_Int32 nOpCode = aIt->OpCode; switch( eState ) { + // #i107275# accept OPCODE_SEP and OPCODE_LIST as separator token case STATE_REF: - if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; + if( nOpCode == OPCODE_SEP ) eState = STATE_SEP; + else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel ); else eState = STATE_ERROR; break; case STATE_SEP: if( nOpCode == OPCODE_PUSH ) eState = lclProcessRef( orRanges, aIt->Data, bAllowRelative, nFilterBySheet ); + else if( nOpCode == OPCODE_SEP ) eState = STATE_SEP; else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; else if( nOpCode == OPCODE_OPEN ) eState = lclProcessOpen( nParenLevel ); else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel ); @@ -1669,13 +1672,15 @@ void FormulaProcessorBase::extractCellRangeList( ApiCellRangeList& orRanges, break; case STATE_OPEN: if( nOpCode == OPCODE_PUSH ) eState = lclProcessRef( orRanges, aIt->Data, bAllowRelative, nFilterBySheet ); + else if( nOpCode == OPCODE_SEP ) eState = STATE_SEP; else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; else if( nOpCode == OPCODE_OPEN ) eState = lclProcessOpen( nParenLevel ); else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel ); else eState = STATE_ERROR; break; case STATE_CLOSE: - if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; + if( nOpCode == OPCODE_SEP ) eState = STATE_SEP; + else if( nOpCode == OPCODE_LIST ) eState = STATE_SEP; else if( nOpCode == OPCODE_CLOSE ) eState = lclProcessClose( nParenLevel ); else eState = STATE_ERROR; break; diff --git a/oox/source/xls/pivottablebuffer.cxx b/oox/source/xls/pivottablebuffer.cxx index 73404d29612f..361a3c00131b 100644 --- a/oox/source/xls/pivottablebuffer.cxx +++ b/oox/source/xls/pivottablebuffer.cxx @@ -221,7 +221,7 @@ OUString lclReadPivotString( const WorkbookHelper& rHelper, BiffInputStream& rSt { if( nLen == BIFF_PT_NOSTRING ) return OUString(); - return (rHelper.getBiff() == BIFF8) ? rStrm.readUniString( nLen ) : rStrm.readCharArrayUC( nLen, rHelper.getTextEncoding() ); + return (rHelper.getBiff() == BIFF8) ? rStrm.readUniStringBody( nLen ) : rStrm.readCharArrayUC( nLen, rHelper.getTextEncoding() ); } } // namespace diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx index dc7456e1e4c9..3e69266592c7 100644 --- a/oox/source/xls/stylesbuffer.cxx +++ b/oox/source/xls/stylesbuffer.cxx @@ -1,3 +1,4 @@ + /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -29,7 +30,7 @@ ************************************************************************/ #include "oox/xls/stylesbuffer.hxx" -#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> #include <com/sun/star/container/XNameAccess.hpp> #include <com/sun/star/awt/FontDescriptor.hpp> #include <com/sun/star/awt/FontFamily.hpp> @@ -65,8 +66,7 @@ using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::UNO_SET_THROW; -using ::com::sun::star::container::XEnumerationAccess; -using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::container::XIndexAccess; using ::com::sun::star::container::XNameAccess; using ::com::sun::star::container::XNamed; using ::com::sun::star::awt::FontDescriptor; @@ -2526,30 +2526,27 @@ void Dxf::finalizeImport() mxFill->finalizeImport(); } -const OUString& Dxf::createDxfStyle( sal_Int32 nDxfId ) +void Dxf::writeToPropertyMap( PropertyMap& rPropMap ) const { - if( maFinalName.getLength() == 0 ) - { - maFinalName = OUStringBuffer( CREATE_OUSTRING( "ConditionalStyle_" ) ).append( nDxfId + 1 ).makeStringAndClear(); - Reference< XStyle > xStyle = createStyleObject( maFinalName, false ); - // write style formatting properties - PropertyMap aPropMap; - if( mxFont.get() ) - mxFont->writeToPropertyMap( aPropMap, FONT_PROPTYPE_CELL ); - if( mxNumFmt.get() ) - mxNumFmt->writeToPropertyMap( aPropMap ); - if( mxAlignment.get() ) - mxAlignment->writeToPropertyMap( aPropMap ); - if( mxProtection.get() ) - mxProtection->writeToPropertyMap( aPropMap ); - if( mxBorder.get() ) - mxBorder->writeToPropertyMap( aPropMap ); - if( mxFill.get() ) - mxFill->writeToPropertyMap( aPropMap ); - PropertySet aPropSet( xStyle ); - aPropSet.setProperties( aPropMap ); - } - return maFinalName; + if( mxFont.get() ) + mxFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL ); + if( mxNumFmt.get() ) + mxNumFmt->writeToPropertyMap( rPropMap ); + if( mxAlignment.get() ) + mxAlignment->writeToPropertyMap( rPropMap ); + if( mxProtection.get() ) + mxProtection->writeToPropertyMap( rPropMap ); + if( mxBorder.get() ) + mxBorder->writeToPropertyMap( rPropMap ); + if( mxFill.get() ) + mxFill->writeToPropertyMap( rPropMap ); +} + +void Dxf::writeToPropertySet( PropertySet& rPropSet ) const +{ + PropertyMap aPropMap; + writeToPropertyMap( aPropMap ); + rPropSet.setProperties( aPropMap ); } // ============================================================================ @@ -2732,6 +2729,11 @@ CellStyleModel::CellStyleModel() : { } +bool CellStyleModel::isBuiltin() const +{ + return mbBuiltin && (mnBuiltinId >= 0); +} + bool CellStyleModel::isDefaultStyle() const { return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL); @@ -2801,11 +2803,6 @@ void CellStyle::importStyle( BiffInputStream& rStrm ) } } -OUString CellStyle::calcInitialStyleName() const -{ - return isBuiltin() ? lclGetBuiltinStyleName( maModel.mnBuiltinId, maModel.maName, maModel.mnLevel ) : maModel.maName; -} - void CellStyle::createCellStyle() { // #i1624# #i1768# ignore unnamed user styles @@ -2832,7 +2829,7 @@ void CellStyle::createCellStyle() // write style formatting properties PropertySet aPropSet( xStyle ); getStyles().writeStyleXfToPropertySet( aPropSet, maModel.mnXfId ); - if( !isDefaultStyle() ) + if( !maModel.isDefaultStyle() ) xStyle->setParentStyle( getStyles().getDefaultStyleName() ); } catch( Exception& ) @@ -2840,47 +2837,182 @@ void CellStyle::createCellStyle() } } -void CellStyle::finalizeImport() +void CellStyle::finalizeImport( const OUString& rFinalName ) { - if( !isBuiltin() || maModel.mbCustom ) + maFinalName = rFinalName; + if( !maModel.isBuiltin() || maModel.mbCustom ) createCellStyle(); } // ============================================================================ -StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ), - maPalette( rHelper ), - maNumFmts( rHelper ), - maDefStyleName( lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() ) ), - mnDefStyleXf( -1 ) +CellStyleBuffer::CellStyleBuffer( const WorkbookHelper& rHelper ) : + WorkbookHelper( rHelper ) +{ +} + +CellStyleRef CellStyleBuffer::importCellStyle( const AttributeList& rAttribs ) +{ + CellStyleRef xCellStyle( new CellStyle( *this ) ); + xCellStyle->importCellStyle( rAttribs ); + insertCellStyle( xCellStyle ); + return xCellStyle; +} + +CellStyleRef CellStyleBuffer::importCellStyle( RecordInputStream& rStrm ) +{ + CellStyleRef xCellStyle( new CellStyle( *this ) ); + xCellStyle->importCellStyle( rStrm ); + insertCellStyle( xCellStyle ); + return xCellStyle; +} + +CellStyleRef CellStyleBuffer::importStyle( BiffInputStream& rStrm ) { - /* Reserve style names that are built-in in Calc. This causes that + CellStyleRef xCellStyle( new CellStyle( *this ) ); + xCellStyle->importStyle( rStrm ); + insertCellStyle( xCellStyle ); + return xCellStyle; +} + +void CellStyleBuffer::finalizeImport() +{ + // calculate final names of all styles + typedef RefMap< OUString, CellStyle, IgnoreCaseCompare > CellStyleNameMap; + CellStyleNameMap aCellStyles; + CellStyleVector aConflictNameStyles; + + /* First, reserve style names that are built-in in Calc. This causes that imported cell styles get different unused names and thus do not try to overwrite these built-in styles. For BIFF4 workbooks (which contain a - separate list of cell styles per sheet), reserve all existing names if + separate list of cell styles per sheet), reserve all existing styles if current sheet is not the first sheet (this styles buffer will be constructed again for every new sheet). This will create unique names - for styles in different sheets with the same name. */ + for styles in different sheets with the same name. Assuming that the + BIFF4W import filter is never used to import from clipboard... */ bool bReserveAll = (getFilterType() == FILTER_BIFF) && (getBiff() == BIFF4) && isWorkbookFile() && (getCurrentSheetIndex() > 0); try { - Reference< XEnumerationAccess > xCellStylesEA( getStyleFamily( false ), UNO_QUERY_THROW ); - Reference< XEnumeration > xCellStylesEnum( xCellStylesEA->createEnumeration(), UNO_SET_THROW ); - while( xCellStylesEnum->hasMoreElements() ) + // unfortunately, com.sun.star.style.StyleFamily does not implement XEnumerationAccess... + Reference< XIndexAccess > xStyleFamilyIA( getStyleFamily( false ), UNO_QUERY_THROW ); + for( sal_Int32 nIndex = 0, nCount = xStyleFamilyIA->getCount(); nIndex < nCount; ++nIndex ) { - Reference< XStyle > xCellStyle( xCellStylesEnum->nextElement(), UNO_QUERY_THROW ); - if( bReserveAll || !xCellStyle->isUserDefined() ) + Reference< XStyle > xStyle( xStyleFamilyIA->getByIndex( nIndex ), UNO_QUERY_THROW ); + if( bReserveAll || !xStyle->isUserDefined() ) { - Reference< XNamed > xCellStyleName( xCellStyle, UNO_QUERY_THROW ); + Reference< XNamed > xStyleName( xStyle, UNO_QUERY_THROW ); // create an empty entry by using ::std::map<>::operator[] - maCellStylesByName[ xCellStyleName->getName() ]; + aCellStyles[ xStyleName->getName() ]; } } } catch( Exception& ) { } + + /* Calculate names of built-in styles. Store styles with reserved names + in the aConflictNameStyles list. */ + for( CellStyleVector::iterator aIt = maBuiltinStyles.begin(), aEnd = maBuiltinStyles.end(); aIt != aEnd; ++aIt ) + { + const CellStyleModel& rModel = (*aIt)->getModel(); + OUString aStyleName = lclGetBuiltinStyleName( rModel.mnBuiltinId, rModel.maName, rModel.mnLevel ); + OSL_ENSURE( bReserveAll || (aCellStyles.count( aStyleName ) == 0), + "CellStyleBuffer::finalizeImport - multiple styles with equal built-in identifier" ); + if( aCellStyles.count( aStyleName ) > 0 ) + aConflictNameStyles.push_back( *aIt ); + else + aCellStyles[ aStyleName ] = *aIt; + } + + /* Calculate names of user defined styles. Store styles with reserved + names in the aConflictNameStyles list. */ + for( CellStyleVector::iterator aIt = maUserStyles.begin(), aEnd = maUserStyles.end(); aIt != aEnd; ++aIt ) + { + const CellStyleModel& rModel = (*aIt)->getModel(); + // #i1624# #i1768# ignore unnamed user styles + if( rModel.maName.getLength() > 0 ) + { + if( aCellStyles.count( rModel.maName ) > 0 ) + aConflictNameStyles.push_back( *aIt ); + else + aCellStyles[ rModel.maName ] = *aIt; + } + } + + // find unused names for all styles with conflicting names + for( CellStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt ) + { + const CellStyleModel& rModel = (*aIt)->getModel(); + OUString aUnusedName; + sal_Int32 nIndex = 0; + do + { + aUnusedName = OUStringBuffer( rModel.maName ).append( sal_Unicode( ' ' ) ).append( ++nIndex ).makeStringAndClear(); + } + while( aCellStyles.count( aUnusedName ) > 0 ); + aCellStyles[ aUnusedName ] = *aIt; + } + + // set final names and create user-defined and modified built-in cell styles + aCellStyles.forEachMemWithKey( &CellStyle::finalizeImport ); +} + +sal_Int32 CellStyleBuffer::getDefaultXfId() const +{ + return mxDefStyle.get() ? mxDefStyle->getModel().mnXfId : -1; +} + +OUString CellStyleBuffer::getDefaultStyleName() const +{ + return createCellStyle( mxDefStyle ); +} + +OUString CellStyleBuffer::createCellStyle( sal_Int32 nXfId ) const +{ + return createCellStyle( maStylesByXf.get( nXfId ) ); +} + +// private -------------------------------------------------------------------- + +void CellStyleBuffer::insertCellStyle( CellStyleRef xCellStyle ) +{ + const CellStyleModel& rModel = xCellStyle->getModel(); + if( rModel.mnXfId >= 0 ) + { + // insert into the built-in map or user defined map + (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle ); + + // insert into the XF identifier map + OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" ); + maStylesByXf[ rModel.mnXfId ] = xCellStyle; + + // remember default cell style + if( rModel.isDefaultStyle() ) + mxDefStyle = xCellStyle; + } +} + +OUString CellStyleBuffer::createCellStyle( const CellStyleRef& rxCellStyle ) const +{ + if( rxCellStyle.get() ) + { + rxCellStyle->createCellStyle(); + const OUString& rStyleName = rxCellStyle->getFinalStyleName(); + if( rStyleName.getLength() > 0 ) + return rStyleName; + } + // on error: fallback to default style + return lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() ); +} + +// ============================================================================ + +StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) : + WorkbookHelper( rHelper ), + maPalette( rHelper ), + maNumFmts( rHelper ), + maCellStyles( rHelper ) +{ } FontRef StylesBuffer::createFont( sal_Int32* opnFontId ) @@ -2948,10 +3080,7 @@ NumberFormatRef StylesBuffer::importNumFmt( const AttributeList& rAttribs ) CellStyleRef StylesBuffer::importCellStyle( const AttributeList& rAttribs ) { - CellStyleRef xCellStyle( new CellStyle( *this ) ); - xCellStyle->importCellStyle( rAttribs ); - insertCellStyle( xCellStyle ); - return xCellStyle; + return maCellStyles.importCellStyle( rAttribs ); } void StylesBuffer::importPaletteColor( RecordInputStream& rStrm ) @@ -2966,9 +3095,7 @@ void StylesBuffer::importNumFmt( RecordInputStream& rStrm ) void StylesBuffer::importCellStyle( RecordInputStream& rStrm ) { - CellStyleRef xCellStyle( new CellStyle( *this ) ); - xCellStyle->importCellStyle( rStrm ); - insertCellStyle( xCellStyle ); + maCellStyles.importCellStyle( rStrm ); } void StylesBuffer::importPalette( BiffInputStream& rStrm ) @@ -3019,9 +3146,7 @@ void StylesBuffer::importXf( BiffInputStream& rStrm ) void StylesBuffer::importStyle( BiffInputStream& rStrm ) { - CellStyleRef xCellStyle( new CellStyle( *this ) ); - xCellStyle->importStyle( rStrm ); - insertCellStyle( xCellStyle ); + maCellStyles.importStyle( rStrm ); } void StylesBuffer::finalizeImport() @@ -3046,14 +3171,11 @@ void StylesBuffer::finalizeImport() maStyleXfs.forEachMem( &Xf::finalizeImport ); maCellXfs.forEachMem( &Xf::finalizeImport ); - // conditional formatting - maDxfs.forEachMem( &Dxf::finalizeImport ); + // built-in and user defined cell styles + maCellStyles.finalizeImport(); - // create the default cell style first - if( CellStyle* pDefStyle = maCellStylesById.get( mnDefStyleXf ).get() ) - pDefStyle->createCellStyle(); - // create user-defined and modified built-in cell styles - maCellStylesById.forEachMem( &CellStyle::finalizeImport ); + // differential formatting (for conditional formatting) + maDxfs.forEachMem( &Dxf::finalizeImport ); } sal_Int32 StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const @@ -3092,7 +3214,7 @@ FontRef StylesBuffer::getFontFromCellXf( sal_Int32 nXfId ) const FontRef StylesBuffer::getDefaultFont() const { FontRef xDefFont; - if( const Xf* pXf = getStyleXf( mnDefStyleXf ).get() ) + if( const Xf* pXf = getStyleXf( maCellStyles.getDefaultXfId() ).get() ) xDefFont = pXf->getFont(); // no font from styles - try first loaded font (e.g. BIFF2) if( !xDefFont ) @@ -3107,30 +3229,35 @@ const FontModel& StylesBuffer::getDefaultFontModel() const return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel(); } -const OUString& StylesBuffer::createCellStyle( sal_Int32 nXfId ) const +OUString StylesBuffer::getDefaultStyleName() const { - if( CellStyle* pCellStyle = maCellStylesById.get( nXfId ).get() ) - { - pCellStyle->createCellStyle(); - const OUString& rStyleName = pCellStyle->getFinalStyleName(); - if( rStyleName.getLength() > 0 ) - return rStyleName; - } - // on error: fallback to default style - return maDefStyleName; + return maCellStyles.getDefaultStyleName(); } -const OUString& StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const +OUString StylesBuffer::createCellStyle( sal_Int32 nXfId ) const { - if( Dxf* pDxf = maDxfs.get( nDxfId ).get() ) - return pDxf->createDxfStyle( nDxfId ); - // on error: fallback to default style - return maDefStyleName; + return maCellStyles.createCellStyle( nXfId ); } -const OUString& StylesBuffer::getDefaultStyleName() const +OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const { - return createCellStyle( mnDefStyleXf ); + OUString& rStyleName = maDxfStyles[ nDxfId ]; + if( rStyleName.getLength() == 0 ) + { + if( Dxf* pDxf = maDxfs.get( nDxfId ).get() ) + { + rStyleName = OUStringBuffer( CREATE_OUSTRING( "ConditionalStyle_" ) ).append( nDxfId + 1 ).makeStringAndClear(); + // create the style sheet (this may change rStyleName if such a style already exists) + Reference< XStyle > xStyle = createStyleObject( rStyleName, false ); + // write style formatting properties + PropertySet aPropSet( xStyle ); + pDxf->writeToPropertySet( aPropSet ); + } + // on error: fallback to default style + if( rStyleName.getLength() == 0 ) + rStyleName = maCellStyles.getDefaultStyleName(); + } + return rStyleName; } void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const @@ -3180,43 +3307,6 @@ void StylesBuffer::writeStyleXfToPropertySet( PropertySet& rPropSet, sal_Int32 n pXf->writeToPropertySet( rPropSet ); } -void StylesBuffer::insertCellStyle( CellStyleRef xCellStyle ) -{ - sal_Int32 nXfId = xCellStyle->getXfId(); - OUString aStyleName = xCellStyle->calcInitialStyleName(); - // #i1624# #i1768# ignore unnamed user styles - if( (nXfId >= 0) && (aStyleName.getLength() > 0) ) - { - // insert into the XF identifier map - maCellStylesById[ nXfId ] = xCellStyle; - - // find an unused name - OUString aUnusedName = aStyleName; - sal_Int32 nIndex = 0; - while( maCellStylesByName.count( aUnusedName ) > 0 ) - aUnusedName = OUStringBuffer( aStyleName ).append( sal_Unicode( ' ' ) ).append( ++nIndex ).makeStringAndClear(); - - // move old existing style to new unused name, if new style is built-in - if( xCellStyle->isBuiltin() && (aStyleName != aUnusedName) ) - { - CellStyleRef& rxCellStyle = maCellStylesByName[ aUnusedName ]; - rxCellStyle = maCellStylesByName[ aStyleName ]; - // the entry may be empty if the style name has been reserved in c'tor - if( rxCellStyle.get() ) - rxCellStyle->setFinalStyleName( aUnusedName ); - aUnusedName = aStyleName; - } - - // insert new style - maCellStylesByName[ aUnusedName ] = xCellStyle; - xCellStyle->setFinalStyleName( aUnusedName ); - - // remember XF identifier of default cell style - if( xCellStyle->isDefaultStyle() ) - mnDefStyleXf = nXfId; - } -} - // ============================================================================ } // namespace xls diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index 6a78c838838e..a372ef714633 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -371,7 +371,7 @@ bool BiffWorkbookFragment::importFragment() // try to start a new sheet fragment double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet); ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength ); - BiffFragmentType eSheetFragment = startFragment( getBiff() ); + BiffFragmentType eSheetFragment = startFragment( getBiff(), rWorksheets.getBiffRecordHandle( nWorksheet ) ); sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet ); bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCalcSheet ); } diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx index 2b337050a996..39b292ae0c7b 100644 --- a/oox/source/xls/workbookhelper.cxx +++ b/oox/source/xls/workbookhelper.cxx @@ -250,6 +250,15 @@ TimeCount& WorkbookHelper::getTimeCount( TimerType eType ) const // ============================================================================ +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 #if OSL_DEBUG_LEVEL > 0 : public dbg::WorkbookData diff --git a/oox/source/xls/workbooksettings.cxx b/oox/source/xls/workbooksettings.cxx index e4de0ff2dd0c..3473dbcc330e 100644 --- a/oox/source/xls/workbooksettings.cxx +++ b/oox/source/xls/workbooksettings.cxx @@ -298,6 +298,8 @@ void WorkbookSettings::finalizeImport() // write protection if( maFileSharing.mbRecommendReadOnly || (maFileSharing.mnPasswordHash != 0) ) getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "ReadOnly" ) ] <<= true; + if( maFileSharing.mnPasswordHash != 0 ) + aPropSet.setProperty( PROP_WriteProtectionPassword, static_cast< sal_Int32 >( maFileSharing.mnPasswordHash ) ); // calculation settings Date aNullDate = getNullDate(); diff --git a/oox/source/xls/worksheetbuffer.cxx b/oox/source/xls/worksheetbuffer.cxx index ee2491880c4e..5f19fd55dbcd 100644 --- a/oox/source/xls/worksheetbuffer.cxx +++ b/oox/source/xls/worksheetbuffer.cxx @@ -61,6 +61,7 @@ namespace xls { // ============================================================================ SheetInfoModel::SheetInfoModel() : + mnBiffHandle( -1 ), mnSheetId( -1 ), mnState( XML_visible ) { @@ -111,19 +112,19 @@ void WorksheetBuffer::importSheet( RecordInputStream& rStrm ) void WorksheetBuffer::importSheet( BiffInputStream& rStrm ) { - sal_uInt16 nState = 0; + SheetInfoModel aModel; if( getBiff() >= BIFF5 ) { - rStrm.skip( 4 ); - rStrm >> nState; + rStrm.enableDecoder( false ); + aModel.mnBiffHandle = rStrm.readuInt32(); + rStrm.enableDecoder( true ); + sal_uInt16 nState = rStrm.readuInt16(); + static const sal_Int32 spnStates[] = { XML_visible, XML_hidden, XML_veryHidden }; + aModel.mnState = STATIC_ARRAY_SELECT( spnStates, nState, XML_visible ); } - - SheetInfoModel aModel; aModel.maName = (getBiff() == BIFF8) ? rStrm.readUniStringBody( rStrm.readuInt8() ) : rStrm.readByteStringUC( false, getTextEncoding() ); - static const sal_Int32 spnStates[] = { XML_visible, XML_hidden, XML_veryHidden }; - aModel.mnState = STATIC_ARRAY_SELECT( spnStates, nState, XML_visible ); insertSheet( aModel ); } @@ -143,6 +144,12 @@ OUString WorksheetBuffer::getWorksheetRelId( sal_Int32 nWorksheet ) const return pSheetInfo ? pSheetInfo->maRelId : OUString(); } +sal_Int64 WorksheetBuffer::getBiffRecordHandle( sal_Int32 nWorksheet ) const +{ + const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get(); + return pSheetInfo ? pSheetInfo->mnBiffHandle : -1; +} + sal_Int16 WorksheetBuffer::getCalcSheetIndex( sal_Int32 nWorksheet ) const { const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get(); @@ -250,13 +257,6 @@ void WorksheetBuffer::insertSheet( const SheetInfoModel& rModel ) maSheetInfosByName[ lclQuoteName( rModel.maName ) ] = xSheetInfo; } -bool WorksheetBuffer::SheetNameCompare::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; -} - // ============================================================================ } // namespace xls diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index 3fe45b06a6b2..fda62feb328c 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -88,6 +88,8 @@ const sal_uInt32 BIFF_DATAVAL_NODROPDOWN = 0x00000200; const sal_uInt32 BIFF_DATAVAL_SHOWINPUT = 0x00040000; const sal_uInt32 BIFF_DATAVAL_SHOWERROR = 0x00080000; +const sal_uInt32 BIFF_SHRFEATHEAD_SHEETPROT = 2; + const sal_Int32 OOBIN_OLEOBJECT_CONTENT = 1; const sal_Int32 OOBIN_OLEOBJECT_ICON = 4; const sal_Int32 OOBIN_OLEOBJECT_ALWAYS = 1; @@ -891,7 +893,7 @@ bool BiffWorksheetFragment::importFragment() case BIFF_ID_SCENPROTECT: rWorksheetSett.importScenProtect( mrStrm ); break; case BIFF_ID_SCL: rSheetViewSett.importScl( mrStrm ); break; case BIFF_ID_SHEETPR: rWorksheetSett.importSheetPr( mrStrm ); break; - case BIFF_ID_SHEETPROTECTION: rWorksheetSett.importSheetProtection( mrStrm ); break; + case BIFF_ID_SHAREDFEATHEAD: importSharedFeatHead(); break; case BIFF_ID_STANDARDWIDTH: importStandardWidth(); break; case BIFF_ID_UNCALCED: rWorkbookSett.importUncalced( mrStrm ); break; case BIFF_ID_VCENTER: rPageSett.importVerCenter( mrStrm ); break; @@ -1157,6 +1159,20 @@ void BiffWorksheetFragment::importScenarios() getScenarios().createSheetScenarios( getSheetIndex() ).importScenarios( mrStrm ); } +void BiffWorksheetFragment::importSharedFeatHead() +{ + mrStrm.skip( 12 ); + sal_uInt16 nType = mrStrm.readuInt16(); + mrStrm.skip( 5 ); + switch( nType ) + { + case BIFF_SHRFEATHEAD_SHEETPROT: + if( mrStrm.getRemaining() >= 4 ) + getWorksheetSettings().importSheetProtection( mrStrm ); + break; + } +} + void BiffWorksheetFragment::importStandardWidth() { sal_uInt16 nWidth; diff --git a/oox/source/xls/worksheetsettings.cxx b/oox/source/xls/worksheetsettings.cxx index d791e4801217..c05e471e6814 100644 --- a/oox/source/xls/worksheetsettings.cxx +++ b/oox/source/xls/worksheetsettings.cxx @@ -60,21 +60,21 @@ const sal_uInt16 BIFF_SHEETPR_SYMBOLSRIGHT = 0x0080; const sal_uInt16 BIFF_SHEETPR_FITTOPAGES = 0x0100; const sal_uInt16 BIFF_SHEETPR_SKIPEXT = 0x0200; /// BIFF3-BIFF4 -const sal_uInt16 BIFF_SHEETPROT_OBJECTS = 0x0001; -const sal_uInt16 BIFF_SHEETPROT_SCENARIOS = 0x0002; -const sal_uInt16 BIFF_SHEETPROT_FORMAT_CELLS = 0x0004; -const sal_uInt16 BIFF_SHEETPROT_FORMAT_COLUMNS = 0x0008; -const sal_uInt16 BIFF_SHEETPROT_FORMAT_ROWS = 0x0010; -const sal_uInt16 BIFF_SHEETPROT_INSERT_COLUMNS = 0x0020; -const sal_uInt16 BIFF_SHEETPROT_INSERT_ROWS = 0x0040; -const sal_uInt16 BIFF_SHEETPROT_INSERT_HLINKS = 0x0080; -const sal_uInt16 BIFF_SHEETPROT_DELETE_COLUMNS = 0x0100; -const sal_uInt16 BIFF_SHEETPROT_DELETE_ROWS = 0x0200; -const sal_uInt16 BIFF_SHEETPROT_SELECT_LOCKED = 0x0400; -const sal_uInt16 BIFF_SHEETPROT_SORT = 0x0800; -const sal_uInt16 BIFF_SHEETPROT_AUTOFILTER = 0x1000; -const sal_uInt16 BIFF_SHEETPROT_PIVOTTABLES = 0x2000; -const sal_uInt16 BIFF_SHEETPROT_SELECT_UNLOCKED = 0x4000; +const sal_uInt32 BIFF_SHEETPROT_OBJECTS = 0x00000001; +const sal_uInt32 BIFF_SHEETPROT_SCENARIOS = 0x00000002; +const sal_uInt32 BIFF_SHEETPROT_FORMAT_CELLS = 0x00000004; +const sal_uInt32 BIFF_SHEETPROT_FORMAT_COLUMNS = 0x00000008; +const sal_uInt32 BIFF_SHEETPROT_FORMAT_ROWS = 0x00000010; +const sal_uInt32 BIFF_SHEETPROT_INSERT_COLUMNS = 0x00000020; +const sal_uInt32 BIFF_SHEETPROT_INSERT_ROWS = 0x00000040; +const sal_uInt32 BIFF_SHEETPROT_INSERT_HLINKS = 0x00000080; +const sal_uInt32 BIFF_SHEETPROT_DELETE_COLUMNS = 0x00000100; +const sal_uInt32 BIFF_SHEETPROT_DELETE_ROWS = 0x00000200; +const sal_uInt32 BIFF_SHEETPROT_SELECT_LOCKED = 0x00000400; +const sal_uInt32 BIFF_SHEETPROT_SORT = 0x00000800; +const sal_uInt32 BIFF_SHEETPROT_AUTOFILTER = 0x00001000; +const sal_uInt32 BIFF_SHEETPROT_PIVOTTABLES = 0x00002000; +const sal_uInt32 BIFF_SHEETPROT_SELECT_UNLOCKED = 0x00004000; } // namespace @@ -277,8 +277,7 @@ void WorksheetSettings::importPassword( BiffInputStream& rStrm ) void WorksheetSettings::importSheetProtection( BiffInputStream& rStrm ) { - rStrm.skip( 19 ); - sal_uInt16 nFlags = rStrm.readuInt16(); + sal_uInt32 nFlags = rStrm.readuInt32(); // set flag means protection is disabled maSheetProt.mbObjects = !getFlag( nFlags, BIFF_SHEETPROT_OBJECTS ); maSheetProt.mbScenarios = !getFlag( nFlags, BIFF_SHEETPROT_SCENARIOS ); |