diff options
author | Kurt Zenker <kz@openoffice.org> | 2009-10-14 15:49:17 +0000 |
---|---|---|
committer | Kurt Zenker <kz@openoffice.org> | 2009-10-14 15:49:17 +0000 |
commit | 3da9b5d151a9b0a7072e3092fbce728abb99302a (patch) | |
tree | de30e77d6b15a9a7f2d7d90bef5cafd9c306545b /oox/source | |
parent | c7d108a1ae2ca4b4ccfe1d5237031f088853555c (diff) |
CWS-TOOLING: integrate CWS calc32stopper2
2009-10-01 12:42:16 +0200 dr r276592 : #i104992# and more typos...
2009-10-01 12:42:13 +0200 nn r276591 : #i105512# SetDocOptions: update number formatter if it already exists
2009-09-30 19:03:58 +0200 dr r276573 : #104992# oops, forgotten to skip a byte
2009-09-30 16:07:17 +0200 dr r276560 : #i103540# check valid vector size
2009-09-29 14:20:45 +0200 dr r276529 : dump some more BIFF records
2009-09-29 13:00:22 +0200 dr r276526 : dump some more BIFF records
2009-09-28 14:34:14 +0200 dr r276490 : #i104057# missing exception file
2009-09-28 10:35:42 +0200 dr r276483 : #i105325# set correct format while opening zip package
2009-09-25 19:07:32 +0200 dr r276475 : #i104992# handle cell styles built-in in Calc correctly
2009-09-25 19:06:46 +0200 dr r276474 : #i104992# handle cell styles built-in in Calc correctly
2009-09-25 17:37:28 +0200 dr r276472 : #i105219# missing include
2009-09-25 12:32:24 +0200 dr r276435 : #i10000# rebase error: renamed variable
2009-09-25 11:34:53 +0200 dr r276431 : CWS-TOOLING: rebase CWS calc32stopper2 to trunk@276429 (milestone: DEV300:m60)
2009-09-24 18:59:23 +0200 dr r276427 : 160550# preserve write-protection password in roundtrip
2009-09-24 18:54:43 +0200 dr r276426 : 160550# preserve write-protection password in roundtrip
2009-09-22 11:38:17 +0200 dr r276353 : #160550# the property has to be integer of course
2009-09-21 18:52:06 +0200 dr r276342 : #160550# new internal property WriteProtectinPassword
2009-09-21 18:22:40 +0200 dr r276340 : #i104057# load sheets substreams according to offsets in SHEET records
2009-09-21 18:11:00 +0200 dr r276338 : #i104057# load sheets substreams according to offsets in SHEET records
2009-09-17 20:07:33 +0200 dr r276255 : #i104057# BIFF5/BIFF8: order of sheet substreams may be different to sheet order, use stream offset provided in SHEET records
Diffstat (limited to 'oox/source')
-rw-r--r-- | oox/source/dump/biffdumper.cxx | 18 | ||||
-rw-r--r-- | oox/source/dump/biffdumper.ini | 13 | ||||
-rw-r--r-- | oox/source/dump/xlsbdumper.ini | 3 | ||||
-rw-r--r-- | oox/source/helper/zipstorage.cxx | 16 | ||||
-rw-r--r-- | oox/source/token/properties.txt | 1 | ||||
-rw-r--r-- | oox/source/token/tokenmap.cxx | 1 | ||||
-rw-r--r-- | oox/source/xls/excelhandlers.cxx | 129 | ||||
-rw-r--r-- | oox/source/xls/externallinkbuffer.cxx | 22 | ||||
-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 |
14 files changed, 360 insertions, 220 deletions
diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index da21926e04bf..2e42d2dc8ca8 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -1864,6 +1864,18 @@ void WorkbookStreamObject::implDumpRecordBody() if( eBiff >= BIFF8 ) dumpHex< sal_uInt16 >( "flags", "CHPIE-FLAGS" ); break; + case BIFF_ID_CHPIVOTFLAGS: + dumpRepeatedRecId(); + dumpUnused( 2 ); + dumpHex< sal_uInt16 >( "flags", "CHPIVOTFLAGS-FLAGS" ); + break; + + case BIFF8_ID_CHPIVOTREF: + dumpRepeatedRecId(); + dumpUnused( 4 ); + dumpUniString( "ref", BIFF_STR_8BITLENGTH ); + break; + case BIFF_ID_CHPLOTGROWTH: dumpFix< sal_Int32 >( "horizontal-growth" ); dumpFix< sal_Int32 >( "vertical-growth" ); @@ -2786,6 +2798,10 @@ void WorkbookStreamObject::implDumpRecordBody() dumpColorABGR( "grid-color" ); break; + case BIFF_ID_WRITEACCESS: + dumpString( "user-name", BIFF_STR_8BITLENGTH ); + break; + case BIFF_ID_XCT: dumpDec< sal_uInt16 >( "crn-count" ); if( eBiff == BIFF8 ) dumpDec< sal_Int16 >( "sheet-idx" ); @@ -2864,7 +2880,7 @@ OUString WorkbookStreamObject::dumpPivotString( const String& rName, sal_uInt16 if( nStrLen != BIFF_PT_NOSTRING ) { aString = (getBiff() == BIFF8) ? - getBiffStream().readUniString( nStrLen ) : + getBiffStream().readUniStringBody( nStrLen ) : getBiffStream().readCharArrayUC( nStrLen, getBiffData().getTextEncoding() ); writeStringItem( rName, aString ); } diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index e9766865dd8b..cc9a5d11427a 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -308,8 +308,8 @@ multilist=RECORD-NAMES-BIFF5 0x0098=,,,FILTERMODE,,AUTOFILTERINFO,AUTOFILTER, 0x00A8=,,,,,,SCENARIOS,SCENARIO 0x00B0=PTDEFINITION,PTFIELD,PTFITEM,,PTROWCOLFIELDS,PTROWCOLITEMS,PTPAGEFIELDS, - 0x00B8=DOCROUTE,RECIPNAME,,,SHAREDFMLA,MULTRK,MULTBLANK, - 0x00C0=,MMS,ADDMENU,DELMENU,,PTDATAFIELD,PCDEFINITION,PCDFIELD + 0x00B8=DOCROUTE,RECIPNAME,,,SHAREDFMLA,MULTRK,MULTBLANK,TOOLBARHDR + 0x00C0=TOOLBAREND,MMS,ADDMENU,DELMENU,,PTDATAFIELD,PCDEFINITION,PCDFIELD 0x00C8=PCITEM_INDEXLIST,PCITEM_DOUBLE,PCITEM_BOOL,PCITEM_ERROR,PCITEM_INTEGER,PCITEM_STRING,PCITEM_DATE,PCITEM_MISSING 0x00D0=SXTBL,SXTBRGITEM,SXTBPG,OBPROJ,,PIVOTCACHE,RSTRING,DBCELL 0x00D8=PCDFRANGEPR,PCDFDISCRETEPR,BOOKBOOL,REVERT,SXEXT|PARAMQRY,SCENPROTECT,OLESIZE,UDDESC @@ -342,9 +342,10 @@ multilist=RECORD-NAMES-BIFF8 0x01A8=,USERBVIEW,USERSVIEWBEGIN,USERSVIEWEND,,QSI,EXTERNALBOOK,PROT4REV 0x01B0=CFHEADER,CFRULE,DATAVALIDATIONS,,,DCONBINAME,TXO,REFRESHALL 0x01B8=HYPERLINK,NLRDELNAME,CODENAME,PCDFSQLTYPE,PROT4REVPASS,,DATAVALIDATION, + 0x01C0=XL9FILE,,,,,,, 0x0800=SCREENTIP,,,WEBQRYSETTINGS,WEBQRYTABLES,,, 0x0850=CHFRINFO,CHFRWRAPPER,CHFRBLOCKBEGIN,CHFRBLOCKEND,,,,CHFRUNITPROPS - 0x0858=CHPIVOTREF,,,,,,, + 0x0858=CHPIVOTREF,CHPIVOTFLAGS,,,,,, 0x0860=,,SHEETLAYOUT,,,,,SHEETPROTECTION 0x0868=,,,CHFRLABELPROPS,,,, 0x0890=,,STYLEEXT,,,,, @@ -817,6 +818,12 @@ flagslist=CHPIE-FLAGS 0x0002=connectors end +# CHPIVOTFLAGS --------------------------------------------------------------- + +flagslist=CHPIVOTFLAGS-FLAGS + 0x0001=hide-field-captions +end + # CHRADAR, CHRADARAREA ------------------------------------------------------- flagslist=CHRADAR-FLAGS diff --git a/oox/source/dump/xlsbdumper.ini b/oox/source/dump/xlsbdumper.ini index be6efd2c6af3..34c464c69509 100644 --- a/oox/source/dump/xlsbdumper.ini +++ b/oox/source/dump/xlsbdumper.ini @@ -208,7 +208,7 @@ multilist=RECORD-NAMES 0x01C8=,,,AUTOSORTSCOPE,AUTOSORTSCOPE_END,CONDFORMATTING,CONDFORMATTING_END,CFRULE 0x01D0=CFRULE_END,ICONSET,ICONSET_END,DATABAR,DATABAR_END,COLORSCALE,COLORSCALE_END,CFVO 0x01D8=,COLORS,COLORS_END,RGBCOLOR,PAGEMARGINS,PRINTOPTIONS,PAGESETUP,HEADERFOOTER - 0x01E0=HEADERFOOTER_END,,,,,SHEETFORMATPR,, + 0x01E0=HEADERFOOTER_END,PTCHARTFORMAT,PTCHARTFORMAT_END,PTCHARTFORMATS,PTCHARTFORMATS_END,SHEETFORMATPR,, 0x01E8=,,,,,,HYPERLINK, 0x01F0=,,,,SCENARIOS,SCENARIOS_END,SCENARIO,SCENARIO_END 0x01F8=INPUTCELLS,DXFS,DXFS_END,DXF,TABLESTYLES,TABLESTYLES_END,, @@ -249,6 +249,7 @@ constlist=SIMPLE-RECORDS 0x0159=int32,dec,count 0x017E=int32,dec,item-index 0x01DD=uint16,hex,flags,PRINTOPTIONS-FLAGS + 0x01E3=int32,dec,count 0x01F9=int32,dec,count 0x0204=int32,dec,type,VOLTYPE-TYPE 0x020D=uint8,dec,error-code,ERRORCODES diff --git a/oox/source/helper/zipstorage.cxx b/oox/source/helper/zipstorage.cxx index 7685b32e2b23..5dd3aa67109b 100644 --- a/oox/source/helper/zipstorage.cxx +++ b/oox/source/helper/zipstorage.cxx @@ -63,7 +63,13 @@ ZipStorage::ZipStorage( // create base storage object try { - mxStorage = ::comphelper::OStorageHelper::GetStorageFromInputStream( rxInStream, rxFactory ); + /* #i105325# ::comphelper::OStorageHelper::GetStorageFromInputStream() + cannot be used here as it will open a storage with format type + 'PackageFormat' that will not work with OOXML packages. + TODO: #i105410# switch to 'OFOPXMLFormat' and use its + implementation of relations handling. */ + mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( + ZIP_STORAGE_FORMAT_STRING, rxInStream, rxFactory ); } catch( Exception& ) { @@ -79,11 +85,9 @@ ZipStorage::ZipStorage( // create base storage object try { - mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OFOPXMLFormat" ) ), - rxStream, - com::sun::star::embed::ElementModes::READWRITE - | com::sun::star::embed::ElementModes::TRUNCATE, - rxFactory ); + using namespace ::com::sun::star::embed::ElementModes; + mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( + OFOPXML_STORAGE_FORMAT_STRING, rxStream, READWRITE | TRUNCATE, rxFactory ); } catch( Exception& ) { diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index 958a9ac24e77..0ecd40ee6595 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -400,6 +400,7 @@ VisualEffect Weight WhiteDay Width +WriteProtectionPassword WritingMode ZoomType ZoomValue diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx index 733b18fd1f01..c01e3662a0d4 100644 --- a/oox/source/token/tokenmap.cxx +++ b/oox/source/token/tokenmap.cxx @@ -29,6 +29,7 @@ ************************************************************************/ #include "oox/token/tokenmap.hxx" +#include <string.h> #include <rtl/strbuf.hxx> #include <rtl/string.hxx> #include "tokens.hxx" 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/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 |