diff options
41 files changed, 677 insertions, 541 deletions
diff --git a/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx b/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx index e0e9511cf71d..a84dbc0cfc4d 100644 --- a/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx @@ -505,7 +505,7 @@ const std::vector< WrappedProperty* > TitleWrapper::createWrappedProperties() ::std::vector< ::chart::WrappedProperty* > aWrappedProperties; aWrappedProperties.push_back( new WrappedTitleStringProperty( m_spChart2ModelContact->m_xContext ) ); - aWrappedProperties.push_back( new WrappedTextRotationProperty() ); + aWrappedProperties.push_back( new WrappedTextRotationProperty( m_eTitleType==TitleHelper::Y_AXIS_TITLE || m_eTitleType==TitleHelper::X_AXIS_TITLE ) ); aWrappedProperties.push_back( new WrappedStackedTextProperty() ); WrappedCharacterHeightProperty::addWrappedProperties( aWrappedProperties, this ); WrappedAutomaticPositionProperties::addWrappedProperties( aWrappedProperties ); diff --git a/chart2/source/controller/chartapiwrapper/WrappedTextRotationProperty.cxx b/chart2/source/controller/chartapiwrapper/WrappedTextRotationProperty.cxx index bd505d6edac5..07532a4ecf22 100644 --- a/chart2/source/controller/chartapiwrapper/WrappedTextRotationProperty.cxx +++ b/chart2/source/controller/chartapiwrapper/WrappedTextRotationProperty.cxx @@ -33,7 +33,9 @@ #include "WrappedTextRotationProperty.hxx" #include "macros.hxx" +#include <com/sun/star/beans/XPropertyState.hpp> +using namespace ::com::sun::star; using ::com::sun::star::uno::Any; using ::rtl::OUString; @@ -43,13 +45,23 @@ namespace chart { //............................................................................. -WrappedTextRotationProperty::WrappedTextRotationProperty() +WrappedTextRotationProperty::WrappedTextRotationProperty( bool bDirectState ) : ::chart::WrappedProperty( C2U( "TextRotation" ), C2U( "TextRotation" ) ) + , m_bDirectState( bDirectState ) { } WrappedTextRotationProperty::~WrappedTextRotationProperty() { } + +beans::PropertyState WrappedTextRotationProperty::getPropertyState( const uno::Reference< beans::XPropertyState >& xInnerPropertyState ) const + throw (beans::UnknownPropertyException, uno::RuntimeException) +{ + if( m_bDirectState ) + return beans::PropertyState_DIRECT_VALUE; + return WrappedProperty::getPropertyState( xInnerPropertyState ); +} + Any WrappedTextRotationProperty::convertInnerToOuterValue( const Any& rInnerValue ) const { Any aRet; diff --git a/chart2/source/controller/chartapiwrapper/WrappedTextRotationProperty.hxx b/chart2/source/controller/chartapiwrapper/WrappedTextRotationProperty.hxx index 38a516bbc1b9..54fbf38e53d7 100644 --- a/chart2/source/controller/chartapiwrapper/WrappedTextRotationProperty.hxx +++ b/chart2/source/controller/chartapiwrapper/WrappedTextRotationProperty.hxx @@ -40,12 +40,17 @@ namespace chart class WrappedTextRotationProperty : public WrappedProperty { public: - WrappedTextRotationProperty(); + WrappedTextRotationProperty( bool bDirectState=false ); virtual ~WrappedTextRotationProperty(); + virtual ::com::sun::star::beans::PropertyState getPropertyState( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState >& xInnerPropertyState ) const + throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + protected: virtual ::com::sun::star::uno::Any convertInnerToOuterValue( const ::com::sun::star::uno::Any& rInnerValue ) const; virtual ::com::sun::star::uno::Any convertOuterToInnerValue( const ::com::sun::star::uno::Any& rOuterValue ) const; + + bool m_bDirectState; }; //............................................................................. diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index 16898be8c2b7..4931b65a1e8e 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -117,6 +117,7 @@ private: com::sun::star::uno::Reference<com::sun::star::uno::XAggregation> GetFormatter(); rtl::OUString maBuildId; + sal_Int32 mnXlsWriteProtPass; protected: const SfxItemPropertySet& GetPropertySet() const { return aPropSet; } diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx index 85f8a4921242..d3d86be58440 100644 --- a/sc/source/core/data/bcaslot.cxx +++ b/sc/source/core/data/bcaslot.cxx @@ -353,6 +353,21 @@ void ScBroadcastAreaSlot::UpdateRemove( UpdateRefMode eUpdateRefMode, } +void ScBroadcastAreaSlot::UpdateRemoveArea( ScBroadcastArea* pArea ) +{ + ScBroadcastAreas::iterator aIter( aBroadcastAreaTbl.find( pArea)); + if (aIter == aBroadcastAreaTbl.end()) + return; + if (*aIter != pArea) + DBG_ERRORFILE( "UpdateRemoveArea: area pointer mismatch"); + else + { + aBroadcastAreaTbl.erase( aIter); + pArea->DecRef(); + } +} + + void ScBroadcastAreaSlot::UpdateInsert( ScBroadcastArea* pArea ) { ::std::pair< ScBroadcastAreas::iterator, bool > aPair = @@ -732,6 +747,50 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas( } } + // Updating an area's range will modify the hash key, remove areas from all + // affected slots. Will be reinserted later with the updated range. + ScBroadcastArea* pChain = pUpdateChain; + while (pChain) + { + ScBroadcastArea* pArea = pChain; + pChain = pArea->GetUpdateChainNext(); + ScRange aRange( pArea->GetRange()); + // remove from slots + for (SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab() && pArea->GetRef(); ++nTab) + { + TableSlotsMap::iterator iTab( aTableSlotsMap.find( nTab)); + if (iTab == aTableSlotsMap.end()) + { + DBG_ERRORFILE( "UpdateBroadcastAreas: Where's the TableSlot?!?"); + continue; // for + } + ScBroadcastAreaSlot** ppSlots = (*iTab).second->getSlots(); + SCSIZE nStart, nEnd, nRowBreak; + ComputeAreaPoints( aRange, nStart, nEnd, nRowBreak ); + SCSIZE nOff = nStart; + SCSIZE nBreak = nOff + nRowBreak; + ScBroadcastAreaSlot** pp = ppSlots + nOff; + while ( nOff <= nEnd && pArea->GetRef() ) + { + if (*pp) + (*pp)->UpdateRemoveArea( pArea); + if ( nOff < nBreak ) + { + ++nOff; + ++pp; + } + else + { + nStart += BCA_SLOTS_ROW; + nOff = nStart; + pp = ppSlots + nOff; + nBreak = nOff + nRowBreak; + } + } + } + + } + // shift sheets if (nDz) { diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 9fc4b09f21af..17650028db70 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -1734,11 +1734,8 @@ const ScDocOptions& ScDocument::GetDocOptions() const void ScDocument::SetDocOptions( const ScDocOptions& rOpt ) { - USHORT d,m,y; - DBG_ASSERT( pDocOptions, "No DocOptions! :-(" ); *pDocOptions = rOpt; - rOpt.GetDate( d,m,y ); xPoolHelper->SetFormTableOpt(rOpt); } diff --git a/sc/source/core/data/poolhelp.cxx b/sc/source/core/data/poolhelp.cxx index ff8f7bb76c5c..d85e16ad135f 100644 --- a/sc/source/core/data/poolhelp.cxx +++ b/sc/source/core/data/poolhelp.cxx @@ -95,14 +95,29 @@ SvNumberFormatter* ScPoolHelper::GetFormTable() const pFormTable->SetColorLink( LINK( m_pSourceDoc, ScDocument, GetUserDefinedColor ) ); pFormTable->SetEvalDateFormat( NF_EVALDATEFORMAT_INTL_FORMAT ); + UseDocOptions(); // null date, year2000, std precision + } + return pFormTable; +} + +void ScPoolHelper::UseDocOptions() const +{ + if (pFormTable) + { USHORT d,m,y; aOpt.GetDate( d,m,y ); pFormTable->ChangeNullDate( d,m,y ); pFormTable->ChangeStandardPrec( (USHORT)aOpt.GetStdPrecision() ); pFormTable->SetYear2000( aOpt.GetYear2000() ); } - return pFormTable; } + +void ScPoolHelper::SetFormTableOpt(const ScDocOptions& rOpt) +{ + aOpt = rOpt; + UseDocOptions(); // #i105512# if the number formatter exists, update its settings +} + void ScPoolHelper::SourceDocumentGone() { // reset all pointers to the source document diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx index ef2f77b55684..79335a35fa7e 100644 --- a/sc/source/core/inc/bcaslot.hxx +++ b/sc/source/core/inc/bcaslot.hxx @@ -192,6 +192,7 @@ public: void UpdateRemove( UpdateRefMode eUpdateRefMode, const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ); + void UpdateRemoveArea( ScBroadcastArea* pArea ); void UpdateInsert( ScBroadcastArea* pArea ); }; diff --git a/sc/source/core/inc/poolhelp.hxx b/sc/source/core/inc/poolhelp.hxx index a60b8db462ab..00474d63c080 100644 --- a/sc/source/core/inc/poolhelp.hxx +++ b/sc/source/core/inc/poolhelp.hxx @@ -54,6 +54,8 @@ private: mutable SfxItemPool* pEnginePool; // EditEnginePool ScDocument* m_pSourceDoc; + void UseDocOptions() const; + public: ScPoolHelper( ScDocument* pSourceDoc ); virtual ~ScPoolHelper(); @@ -68,7 +70,7 @@ public: SfxItemPool* GetEditPool() const; SfxItemPool* GetEnginePool() const; - void SetFormTableOpt(const ScDocOptions& rOpt) { aOpt = rOpt; } + void SetFormTableOpt(const ScDocOptions& rOpt); }; #endif diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index a8ca4be2b5b6..df7131397aef 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -2278,14 +2278,16 @@ Label_MaskStateMachine: static const int kQuote = (1 << 4); // Past ' closing quote. static const int kClose = (1 << 5); + // Encountered # file/sheet separator. + static const int kFileSep = (1 << 6); // Past . sheet name separator. - static const int kPast = (1 << 6); + static const int kPast = (1 << 7); // Marked name $$ follows sheet name separator, detected // while we're still on the separator. Will be cleared when // entering the name. - static const int kMarkAhead = (1 << 7); + static const int kMarkAhead = (1 << 8); // In marked defined name. - static const int kDefName = (1 << 8); + static const int kDefName = (1 << 9); bool bAddToSymbol = true; if ((nMask & SC_COMPILER_C_ODF_RBRACKET) && !(nRefInName & kOpen)) @@ -2309,7 +2311,9 @@ Label_MaskStateMachine: { // Not in col/row yet. - if ('$' == c && '$' == pSrc[0] && !(nRefInName & kOpen)) + if (SC_COMPILER_FILE_TAB_SEP == c && (nRefInName & kFileSep)) + nRefInName = 0; + else if ('$' == c && '$' == pSrc[0] && !(nRefInName & kOpen)) { nRefInName &= ~kMarkAhead; if (!(nRefInName & kDefName)) @@ -2356,16 +2360,20 @@ Label_MaskStateMachine: } else { - if ('\'' == pSrc[0]) - { - // escapes embedded quote - nRefInName |= kQuote; - } - else + switch (pSrc[0]) { - // quote not followed by quote => close - nRefInName |= kClose; - nRefInName &= ~kOpen; + case '\'': + // escapes embedded quote + nRefInName |= kQuote; + break; + case SC_COMPILER_FILE_TAB_SEP: + // sheet name should follow + nRefInName |= kFileSep; + // fallthru + default: + // quote not followed by quote => close + nRefInName |= kClose; + nRefInName &= ~kOpen; } bAddToSymbol = !(nRefInName & kDefName); } diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index d1b08b9cfc68..c72d165c7972 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -144,12 +144,12 @@ static void lcl_AddWorkbookProtection( XclExpRecordList<>& aRecList, ExcTable& s } #endif -static void lcl_AddScenariosAndFilters( XclExpRecordList<>& aRecList, ExcTable& self, SCTAB mnScTab ) +static void lcl_AddScenariosAndFilters( XclExpRecordList<>& aRecList, const XclExpRoot& rRoot, SCTAB nScTab ) { // Scenarios - aRecList.AppendNewRecord( new ExcEScenarioManager( self.GetDoc(), mnScTab ) ); + aRecList.AppendNewRecord( new ExcEScenarioManager( rRoot, nScTab ) ); // filter - aRecList.AppendRecord( self.GetFilterManager().CreateRecord( mnScTab ) ); + aRecList.AppendRecord( rRoot.GetFilterManager().CreateRecord( nScTab ) ); } @@ -205,20 +205,47 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) rR.pObjRecs = NULL; // per sheet + sal_uInt16 nWriteProtHash = 0; + if( SfxObjectShell* pDocShell = GetDocShell() ) + { + ScfPropertySet aPropSet( pDocShell->GetModel() ); + sal_Int32 nApiHash = 0; + if( aPropSet.GetProperty( nApiHash, CREATE_OUSTRING( "WriteProtectionPassword" ) ) && (0 < nApiHash) && (nApiHash <= SAL_MAX_UINT16) ) + { + nWriteProtHash = static_cast< sal_uInt16 >( nApiHash ); + Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT ) ); + } + } + + // TODO: correct codepage for BIFF5? + sal_uInt16 nCodePage = XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5) ? RTL_TEXTENCODING_MS_1252 : RTL_TEXTENCODING_UNICODE ); + if( GetBiff() <= EXC_BIFF5 ) + { + Add( new XclExpEmptyRecord( EXC_ID_INTERFACEHDR ) ); + Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) ); + Add( new XclExpEmptyRecord( EXC_ID_TOOLBARHDR ) ); + Add( new XclExpEmptyRecord( EXC_ID_TOOLBAREND ) ); + Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND ) ); Add( new ExcDummy_00 ); + } else { - if ( IsDocumentEncrypted() ) - Add( new XclExpFilePass(GetRoot()) ); - - Add( new XclExpInterfaceHdr ); - Add( new XclExpMMS ); - Add( new XclExpInterfaceEnd ); + if( IsDocumentEncrypted() ) + Add( new XclExpFilePass( GetRoot() ) ); + Add( new XclExpInterfaceHdr( nCodePage ) ); + Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) ); + Add( new XclExpEmptyRecord( EXC_ID_INTERFACEEND ) ); Add( new XclExpWriteAccess ); - Add( new XclExpCodePage ); - Add( new XclExpDSF ); - Add( new XclExpExcel9File ); + } + + Add( new XclExpFileSharing( GetRoot(), nWriteProtHash ) ); + Add( new XclExpUInt16Record( EXC_ID_CODEPAGE, nCodePage ) ); + + if( GetBiff() == EXC_BIFF8 ) + { + Add( new XclExpBoolRecord( EXC_ID_DSF, false ) ); + Add( new XclExpEmptyRecord( EXC_ID_XL9FILE ) ); rR.pTabId = new XclExpChTrTabId( Max( nExcTabCount, nCodenames ) ); Add( rR.pTabId ); if( HasVbaStorage() ) @@ -228,10 +255,10 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) if( rCodeName.Len() ) Add( new XclCodename( rCodeName ) ); } - - Add( new XclExpFnGroupCount ); } + Add( new XclExpUInt16Record( EXC_ID_FNGROUPCOUNT, 14 ) ); + // erst Namen- und Tabellen-Eintraege aufbauen String aName; @@ -473,7 +500,7 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx ) aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) ); if ( eBiff == EXC_BIFF8 ) - lcl_AddScenariosAndFilters( aRecList, *this, mnScTab ); + lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab ); // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records aRecList.AppendRecord( mxCellTable ); @@ -585,7 +612,7 @@ void ExcTable::FillAsXmlTable( size_t nCodeNameIdx ) // web queries Add( new XclExpWebQueryBuffer( GetRoot() ) ); - lcl_AddScenariosAndFilters( aRecList, *this, mnScTab ); + lcl_AddScenariosAndFilters( aRecList, GetRoot(), mnScTab ); // MERGEDCELLS record, generated by the cell table aRecList.AppendRecord( mxCellTable->CreateRecord( EXC_ID_MERGEDCELLS ) ); diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx index 1d209b91bc68..deaa3b375c6d 100644 --- a/sc/source/filter/excel/excimp8.cxx +++ b/sc/source/filter/excel/excimp8.cxx @@ -165,14 +165,14 @@ void ImportExcel8::Boundsheet( void ) UINT8 nLen; UINT16 nGrbit; - aIn.Ignore( 4 ); + aIn.DisableDecryption(); + maSheetOffsets.push_back( aIn.ReaduInt32() ); + aIn.EnableDecryption(); aIn >> nGrbit >> nLen; String aName( aIn.ReadUniString( nLen ) ); GetTabInfo().AppendXclTabName( aName, nBdshtTab ); - *pExcRoot->pTabNameBuff << aName; - SCTAB nScTab = static_cast< SCTAB >( nBdshtTab ); if( nScTab > 0 ) { diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx index bff8d4cba246..4ee5f70dc938 100644 --- a/sc/source/filter/excel/excrecds.cxx +++ b/sc/source/filter/excel/excrecds.cxx @@ -107,17 +107,10 @@ using ::rtl::OString; //--------------------------------------------------------- class ExcDummy_00 - const BYTE ExcDummy_00::pMyData[] = { - 0xe1, 0x00, 0x00, 0x00, // INTERFACEHDR - 0xc1, 0x00, 0x02, 0x00, 0x00, 0x00, // MMS - 0xbf, 0x00, 0x00, 0x00, // TOOLBARHDR - 0xc0, 0x00, 0x00, 0x00, // TOOLBAREND - 0xe2, 0x00, 0x00, 0x00, // INTERFACEEND - 0x5c, 0x00, 0x20, 0x00, 0x04, 0x4d, 0x72, 0x20, 0x58, // WRITEACCESS + 0x5c, 0x00, 0x20, 0x00, 0x04, 'C', 'a', 'l', 'c', // WRITEACCESS 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x42, 0x00, 0x02, 0x00, 0xe4, 0x04, // CODEPAGE - 0x9c, 0x00, 0x02, 0x00, 0x0e, 0x00 // FNGROUPCOUNT + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; const sal_Size ExcDummy_00::nMyLen = sizeof( ExcDummy_00::pMyData ); @@ -315,27 +308,6 @@ sal_Size ExcEof::GetLen( void ) const -//----------------------------------------------------- class ExcFngroupcount - - -void ExcFngroupcount::SaveCont( XclExpStream& rStrm ) -{ - rStrm << ( UINT16 ) 0x000E; // copied from Excel -} - - -UINT16 ExcFngroupcount::GetNum( void ) const -{ - return 0x009C; -} - - -sal_Size ExcFngroupcount::GetLen( void ) const -{ - return 2; -} - - - //--------------------------------------------------------- class ExcDummy_00 - sal_Size ExcDummy_00::GetLen( void ) const diff --git a/sc/source/filter/excel/exctools.cxx b/sc/source/filter/excel/exctools.cxx index 11400ca20742..d698278d9d3c 100644 --- a/sc/source/filter/excel/exctools.cxx +++ b/sc/source/filter/excel/exctools.cxx @@ -68,7 +68,6 @@ RootData::RootData( void ) { eDateiTyp = BiffX; pExtSheetBuff = NULL; - pTabNameBuff = NULL; pShrfmlaBuff = NULL; pExtNameBuff = NULL; pFmlaConverter = NULL; @@ -90,7 +89,6 @@ RootData::RootData( void ) RootData::~RootData() { delete pExtSheetBuff; - delete pTabNameBuff; delete pShrfmlaBuff; delete pExtNameBuff; delete pAutoFilterBuffer; diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx index 5a0ae1f9a972..9b868f4d3268 100644 --- a/sc/source/filter/excel/impop.cxx +++ b/sc/source/filter/excel/impop.cxx @@ -136,7 +136,6 @@ ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ): pExcRoot->pIR = this; // ExcRoot -> XclImpRoot pExcRoot->eDateiTyp = BiffX; pExcRoot->pExtSheetBuff = new ExtSheetBuffer( pExcRoot ); //&aExtSheetBuff; - pExcRoot->pTabNameBuff = new NameBuffer( pExcRoot ); //&aTabNameBuff; pExcRoot->pShrfmlaBuff = new ShrfmlaBuffer( pExcRoot ); //&aShrfrmlaBuff; pExcRoot->pExtNameBuff = new ExtNameBuff ( *this ); @@ -180,9 +179,19 @@ void ImportExcel::ReadFileSharing() { sal_uInt16 nRecommendReadOnly, nPasswordHash; maStrm >> nRecommendReadOnly >> nPasswordHash; + if( (nRecommendReadOnly != 0) || (nPasswordHash != 0) ) if( SfxItemSet* pItemSet = GetMedium().GetItemSet() ) pItemSet->Put( SfxBoolItem( SID_DOC_READONLY, TRUE ) ); + + if( nPasswordHash != 0 ) + { + if( SfxObjectShell* pDocShell = GetDocShell() ) + { + ScfPropertySet aPropSet( pDocShell->GetModel() ); + aPropSet.SetProperty( CREATE_OUSTRING( "WriteProtectionPassword" ), static_cast< sal_Int32 >( nPasswordHash ) ); + } + } } sal_uInt16 ImportExcel::ReadXFIndex( bool bBiff2 ) @@ -688,14 +697,14 @@ void ImportExcel::Boundsheet( void ) if( GetBiff() == EXC_BIFF5 ) { - aIn.Ignore( 4 ); + aIn.DisableDecryption(); + maSheetOffsets.push_back( aIn.ReaduInt32() ); + aIn.EnableDecryption(); aIn >> nGrbit; } String aName( aIn.ReadByteString( FALSE ) ); - *pExcRoot->pTabNameBuff << aName; - SCTAB nScTab = static_cast< SCTAB >( nBdshtTab ); if( nScTab > 0 ) { diff --git a/sc/source/filter/excel/makefile.mk b/sc/source/filter/excel/makefile.mk index 5b483f04729d..4c94b0712d89 100644 --- a/sc/source/filter/excel/makefile.mk +++ b/sc/source/filter/excel/makefile.mk @@ -121,6 +121,7 @@ EXCEPTIONSFILES = \ $(SLO)$/excimp8.obj \ $(SLO)$/excrecds.obj \ $(SLO)$/expop2.obj \ + $(SLO)$/impop.obj \ $(SLO)$/namebuff.obj \ $(SLO)$/tokstack.obj \ $(SLO)$/xecontent.obj \ diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index a4a286d27171..afa66422ca44 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -99,9 +99,28 @@ FltError ImportExcel::Read( void ) ::std::auto_ptr< ScfSimpleProgressBar > pProgress( new ScfSimpleProgressBar( aIn.GetSvStreamSize(), GetDocShell(), STR_LOAD_DOC ) ); + /* #i104057# Need to track a base position for progress bar calculation, + because sheet substreams may not be in order of sheets. */ + sal_Size nProgressBasePos = 0; + sal_Size nProgressBaseSize = 0; + while( eAkt != Z_Ende ) { - aIn.StartNextRecord(); + if( eAkt == Z_Biff5E ) + { + sal_uInt16 nScTab = GetCurrScTab(); + if( nScTab < maSheetOffsets.size() ) + { + nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos); + nProgressBasePos = maSheetOffsets[ nScTab ]; + aIn.StartNextRecord( nProgressBasePos ); + } + else + eAkt = Z_Ende; + } + else + aIn.StartNextRecord(); + nOpcode = aIn.GetRecId(); if( !aIn.IsValid() ) @@ -124,8 +143,11 @@ FltError ImportExcel::Read( void ) break; } + if( eAkt == Z_Ende ) + break; + if( eAkt != Z_Biff5TPre && eAkt != Z_Biff5WPre ) - pProgress->ProgressAbs( aIn.GetSvStreamPos() ); + pProgress->ProgressAbs( nProgressBaseSize + aIn.GetSvStreamPos() - nProgressBasePos ); switch( eAkt ) { @@ -804,9 +826,28 @@ FltError ImportExcel8::Read( void ) ::std::auto_ptr< ScfSimpleProgressBar > pProgress( new ScfSimpleProgressBar( aIn.GetSvStreamSize(), GetDocShell(), STR_LOAD_DOC ) ); + /* #i104057# Need to track a base position for progress bar calculation, + because sheet substreams may not be in order of sheets. */ + sal_Size nProgressBasePos = 0; + sal_Size nProgressBaseSize = 0; + while( eAkt != EXC_STATE_END ) { - aIn.StartNextRecord(); + if( eAkt == EXC_STATE_BEFORE_SHEET ) + { + sal_uInt16 nScTab = GetCurrScTab(); + if( nScTab < maSheetOffsets.size() ) + { + nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos); + nProgressBasePos = maSheetOffsets[ nScTab ]; + aIn.StartNextRecord( nProgressBasePos ); + } + else + eAkt = EXC_STATE_END; + } + else + aIn.StartNextRecord(); + if( !aIn.IsValid() ) { // #124240# #i63591# finalize table if EOF is missing @@ -830,7 +871,7 @@ FltError ImportExcel8::Read( void ) break; if( eAkt != EXC_STATE_SHEET_PRE && eAkt != EXC_STATE_GLOBALS_PRE ) - pProgress->ProgressAbs( aIn.GetSvStreamPos() ); + pProgress->ProgressAbs( nProgressBaseSize + aIn.GetSvStreamPos() - nProgressBasePos ); sal_uInt16 nRecId = aIn.GetRecId(); diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx index ef15b16030cf..849ac080bb1d 100644 --- a/sc/source/filter/excel/xeformula.cxx +++ b/sc/source/filter/excel/xeformula.cxx @@ -2170,10 +2170,15 @@ void XclExpFmlaCompImpl::PushOperatorPos( sal_uInt16 nTokPos, const XclExpOperan sal_uInt16 XclExpFmlaCompImpl::PopOperandPos() { - DBG_ASSERT( !mxData->maOpPosStack.empty(), "XclExpFmlaCompImpl::PopOperandPos - token stack broken" ); - sal_uInt16 nTokPos = mxData->maOpPosStack.back(); - mxData->maOpPosStack.pop_back(); - return nTokPos; + DBG_ASSERT( !mxData->mbOk || !mxData->maOpPosStack.empty(), "XclExpFmlaCompImpl::PopOperandPos - token stack broken" ); + mxData->mbOk &= !mxData->maOpPosStack.empty(); + if( mxData->mbOk ) + { + sal_uInt16 nTokPos = mxData->maOpPosStack.back(); + mxData->maOpPosStack.pop_back(); + return nTokPos; + } + return 0; } namespace { diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx index 2d920b0a0bd4..dc542a1c1eeb 100644 --- a/sc/source/filter/excel/xichart.cxx +++ b/sc/source/filter/excel/xichart.cxx @@ -2159,7 +2159,9 @@ void XclImpChChart3d::ReadChChart3d( XclImpStream& rStrm ) void XclImpChChart3d::Convert( ScfPropertySet& rPropSet, bool b3dWallChart ) const { namespace cssd = ::com::sun::star::drawing; - DBG_ASSERT( ::get_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS ) == b3dWallChart, "XclImpChChart3d::Convert - wrong wall flag" ); + +// #i104057# do not assert this, written by broken external generators +// DBG_ASSERT( ::get_flag( maData.mnFlags, EXC_CHCHART3D_HASWALLS ) == b3dWallChart, "XclImpChChart3d::Convert - wrong wall flag" ); sal_Int32 nRotationY = 0; sal_Int32 nRotationX = 0; diff --git a/sc/source/filter/excel/xilink.cxx b/sc/source/filter/excel/xilink.cxx index 9033ecc125bd..00268215a5dc 100644 --- a/sc/source/filter/excel/xilink.cxx +++ b/sc/source/filter/excel/xilink.cxx @@ -153,6 +153,7 @@ struct XclImpXti sal_uInt16 mnSupbook; /// Index to SUPBOOK record. sal_uInt16 mnSBTabFirst; /// Index to the first sheet of the range in the SUPBOOK. sal_uInt16 mnSBTabLast; /// Index to the last sheet of the range in the SUPBOOK. + inline explicit XclImpXti() : mnSupbook( SAL_MAX_UINT16 ), mnSBTabFirst( SAL_MAX_UINT16 ), mnSBTabLast( SAL_MAX_UINT16 ) {} }; inline XclImpStream& operator>>( XclImpStream& rStrm, XclImpXti& rXti ) @@ -204,8 +205,10 @@ public: const String& GetMacroName( sal_uInt16 nExtSheet, sal_uInt16 nExtName ) const; private: + /** Returns the specified XTI (link entry from BIFF8 EXTERNSHEET record). */ + const XclImpXti* GetXti( sal_uInt16 nXtiIndex ) const; /** Returns the specified SUPBOOK (external document). */ - const XclImpSupbook* GetSupbook( sal_uInt32 nXtiIndex ) const; + const XclImpSupbook* GetSupbook( sal_uInt16 nXtiIndex ) const; //UNUSED2009-05 /** Returns the SUPBOOK (external workbook) specified by its URL. */ //UNUSED2009-05 const XclImpSupbook* GetSupbook( const String& rUrl ) const; @@ -222,10 +225,10 @@ private: //UNUSED2009-05 sal_uInt16 nSupbook, sal_uInt16 nSBTabStart ) const; private: - typedef ScfDelList< XclImpXti > XclImpXtiList; + typedef ::std::vector< XclImpXti > XclImpXtiVector; typedef ScfDelList< XclImpSupbook > XclImpSupbookList; - XclImpXtiList maXtiList; /// List of all XTI structures. + XclImpXtiVector maXtiList; /// List of all XTI structures. XclImpSupbookList maSupbookList; /// List of external documents. bool mbCreated; /// true = Calc sheets already created. }; @@ -582,15 +585,17 @@ void XclImpLinkManagerImpl::ReadExternsheet( XclImpStream& rStrm ) { sal_uInt16 nXtiCount; rStrm >> nXtiCount; - - XclImpXti* pXti; - while( nXtiCount ) - { - pXti = new XclImpXti; - rStrm >> *pXti; - maXtiList.Append( pXti ); - --nXtiCount; - } + DBG_ASSERT( static_cast< sal_Size >( nXtiCount * 6 ) == rStrm.GetRecLeft(), "XclImpLinkManagerImpl::ReadExternsheet - invalid count" ); + nXtiCount = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nXtiCount, rStrm.GetRecLeft() / 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. */ + XclImpXtiVector aNewEntries( nXtiCount ); + for( XclImpXtiVector::iterator aIt = aNewEntries.begin(), aEnd = aNewEntries.end(); rStrm.IsValid() && (aIt != aEnd); ++aIt ) + rStrm >> *aIt; + maXtiList.insert( maXtiList.begin(), aNewEntries.begin(), aNewEntries.end() ); LoadCachedValues(); } @@ -627,7 +632,7 @@ bool XclImpLinkManagerImpl::IsSelfRef( sal_uInt16 nXtiIndex ) const bool XclImpLinkManagerImpl::GetScTabRange( SCTAB& rnFirstScTab, SCTAB& rnLastScTab, sal_uInt16 nXtiIndex ) const { - if( const XclImpXti* pXti = maXtiList.GetObject( nXtiIndex ) ) + if( const XclImpXti* pXti = GetXti( nXtiIndex ) ) { if (maSupbookList.GetObject(pXti->mnSupbook)) { @@ -671,9 +676,14 @@ const String& XclImpLinkManagerImpl::GetMacroName( sal_uInt16 nExtSheet, sal_uIn return pSupbook ? pSupbook->GetMacroName( nExtName ) : EMPTY_STRING; } -const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt32 nXtiIndex ) const +const XclImpXti* XclImpLinkManagerImpl::GetXti( sal_uInt16 nXtiIndex ) const +{ + return (nXtiIndex < maXtiList.size()) ? &maXtiList[ nXtiIndex ] : 0; +} + +const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt16 nXtiIndex ) const { - const XclImpXti* pXti = maXtiList.GetObject( nXtiIndex ); + const XclImpXti* pXti = GetXti( nXtiIndex ); return pXti ? maSupbookList.GetObject( pXti->mnSupbook ) : 0; } diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx index b168c4389c4c..a040f21b1c4f 100644 --- a/sc/source/filter/excel/xistream.cxx +++ b/sc/source/filter/excel/xistream.cxx @@ -414,6 +414,12 @@ bool XclImpStream::StartNextRecord() return mbValidRec; } +bool XclImpStream::StartNextRecord( sal_Size nNextRecPos ) +{ + mnNextRecPos = nNextRecPos; + return StartNextRecord(); +} + void XclImpStream::ResetRecord( bool bContLookup, sal_uInt16 nAltContId ) { if( mbValidRec ) diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx index a83e203c167d..07368f6db680 100644 --- a/sc/source/filter/excel/xistyle.cxx +++ b/sc/source/filter/excel/xistyle.cxx @@ -968,9 +968,7 @@ XclImpXF::XclImpXF( const XclImpRoot& rRoot ) : XclImpRoot( rRoot ), mpStyleSheet( 0 ), mnXclNumFmt( 0 ), - mnXclFont( 0 ), - mbWasBuiltIn( false ), - mbForceCreate( false ) + mnXclFont( 0 ) { } @@ -1088,31 +1086,61 @@ void XclImpXF::ReadXF( XclImpStream& rStrm ) } } -void XclImpXF::SetStyleName( const String& rStyleName, bool bBuiltIn, bool bForceCreate ) +const ScPatternAttr& XclImpXF::CreatePattern( bool bSkipPoolDefs ) { - DBG_ASSERT( IsStyleXF(), "XclImpXF::SetStyleName - not a style XF" ); - DBG_ASSERT( rStyleName.Len() > 0, "XclImpXF::SetStyleName - style name empty" ); - if( IsStyleXF() && (rStyleName.Len() > 0) ) + if( mpPattern.get() ) + return *mpPattern; + + // create new pattern attribute set + mpPattern.reset( new ScPatternAttr( GetDoc().GetPool() ) ); + SfxItemSet& rItemSet = mpPattern->GetItemSet(); + + // parent cell style + if( IsCellXF() && !mpStyleSheet ) { - maStyleName = rStyleName; - mbWasBuiltIn = bBuiltIn; - mbForceCreate = bForceCreate; + mpStyleSheet = GetXFBuffer().CreateStyleSheet( mnParent ); + if( XclImpXF* pParentXF = GetXFBuffer().GetXF( mnParent ) ) + UpdateUsedFlags( *pParentXF ); } -} -void XclImpXF::ChangeStyleName( const String& rStyleName ) -{ - DBG_ASSERT( IsStyleXF(), "XclImpXF::ChangeStyleName - not a style XF" ); - DBG_ASSERT( rStyleName.Len() > 0, "XclImpXF::ChangeStyleName - new style name empty" ); - DBG_ASSERT( maStyleName.Len() > 0, "XclImpXF::ChangeStyleName - old style name empty" ); - if( IsStyleXF() && (rStyleName.Len() > 0) ) - maStyleName = rStyleName; -} + // cell protection + if( mbProtUsed ) + maProtection.FillToItemSet( rItemSet, bSkipPoolDefs ); -void XclImpXF::CreateUserStyle() -{ - if( IsStyleXF() && mbForceCreate ) - CreateStyleSheet(); + // font + if( mbFontUsed ) + GetFontBuffer().FillToItemSet( rItemSet, EXC_FONTITEM_CELL, mnXclFont, bSkipPoolDefs ); + + // value format + if( mbFmtUsed ) + { + GetNumFmtBuffer().FillToItemSet( rItemSet, mnXclNumFmt, bSkipPoolDefs ); + // Trace occurrences of Windows date formats + GetTracer().TraceDates( mnXclNumFmt ); + } + + // alignment + if( mbAlignUsed ) + maAlignment.FillToItemSet( rItemSet, GetFontBuffer().GetFont( mnXclFont ), bSkipPoolDefs ); + + // border + if( mbBorderUsed ) + { + maBorder.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs ); + GetTracer().TraceBorderLineStyle(maBorder.mnLeftLine > EXC_LINE_HAIR || + maBorder.mnRightLine > EXC_LINE_HAIR || maBorder.mnTopLine > EXC_LINE_HAIR || + maBorder.mnBottomLine > EXC_LINE_HAIR ); + } + + // area + if( mbAreaUsed ) + { + maArea.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs ); + GetTracer().TraceFillPattern(maArea.mnPattern != EXC_PATT_NONE && + maArea.mnPattern != EXC_PATT_SOLID); + } + + return *mpPattern; } void XclImpXF::ApplyPattern( @@ -1175,80 +1203,71 @@ void XclImpXF::UpdateUsedFlags( const XclImpXF& rParentXF ) mbAreaUsed = !rParentXF.mbAreaUsed || !(maArea == rParentXF.maArea); } -const ScPatternAttr& XclImpXF::CreatePattern( bool bSkipPoolDefs ) -{ - if( mpPattern.get() ) - return *mpPattern; - - // create new pattern attribute set - mpPattern.reset( new ScPatternAttr( GetDoc().GetPool() ) ); - SfxItemSet& rItemSet = mpPattern->GetItemSet(); - - // parent cell style - if( IsCellXF() ) - { - if( XclImpXF* pParentXF = GetXFBuffer().GetXF( mnParent ) ) - { - mpStyleSheet = pParentXF->CreateStyleSheet(); - UpdateUsedFlags( *pParentXF ); - } - } - - // cell protection - if( mbProtUsed ) - maProtection.FillToItemSet( rItemSet, bSkipPoolDefs ); +// ---------------------------------------------------------------------------- - // font - if( mbFontUsed ) - GetFontBuffer().FillToItemSet( rItemSet, EXC_FONTITEM_CELL, mnXclFont, bSkipPoolDefs ); +XclImpStyle::XclImpStyle( const XclImpRoot& rRoot ) : + XclImpRoot( rRoot ), + mnXfId( EXC_XF_NOTFOUND ), + mnBuiltinId( EXC_STYLE_USERDEF ), + mnLevel( EXC_STYLE_NOLEVEL ), + mbBuiltin( false ), + mbCustom( false ), + mbHidden( false ), + mpStyleSheet( 0 ) +{ +} - // value format - if( mbFmtUsed ) - { - GetNumFmtBuffer().FillToItemSet( rItemSet, mnXclNumFmt, bSkipPoolDefs ); - // Trace occurrences of Windows date formats - GetTracer().TraceDates( mnXclNumFmt ); - } +void XclImpStyle::ReadStyle( XclImpStream& rStrm ) +{ + DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF3 ); - // alignment - if( mbAlignUsed ) - maAlignment.FillToItemSet( rItemSet, GetFontBuffer().GetFont( mnXclFont ), bSkipPoolDefs ); + sal_uInt16 nXFIndex; + rStrm >> nXFIndex; + mnXfId = nXFIndex & EXC_STYLE_XFMASK; + mbBuiltin = ::get_flag( nXFIndex, EXC_STYLE_BUILTIN ); - // border - if( mbBorderUsed ) + if( mbBuiltin ) { - maBorder.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs ); - GetTracer().TraceBorderLineStyle(maBorder.mnLeftLine > EXC_LINE_HAIR || - maBorder.mnRightLine > EXC_LINE_HAIR || maBorder.mnTopLine > EXC_LINE_HAIR || - maBorder.mnBottomLine > EXC_LINE_HAIR ); + rStrm >> mnBuiltinId >> mnLevel; } - - // area - if( mbAreaUsed ) + else { - maArea.FillToItemSet( rItemSet, GetPalette(), bSkipPoolDefs ); - GetTracer().TraceFillPattern(maArea.mnPattern != EXC_PATT_NONE && - maArea.mnPattern != EXC_PATT_SOLID); + maName = (GetBiff() <= EXC_BIFF5) ? rStrm.ReadByteString( false ) : rStrm.ReadUniString(); + // #i103281# check if this is a new built-in style introduced in XL2007 + if( (GetBiff() == EXC_BIFF8) && (rStrm.GetNextRecId() == EXC_ID_STYLEEXT) && rStrm.StartNextRecord() ) + { + sal_uInt8 nExtFlags; + rStrm.Ignore( 12 ); + rStrm >> nExtFlags; + mbBuiltin = ::get_flag( nExtFlags, EXC_STYLEEXT_BUILTIN ); + mbCustom = ::get_flag( nExtFlags, EXC_STYLEEXT_CUSTOM ); + mbHidden = ::get_flag( nExtFlags, EXC_STYLEEXT_HIDDEN ); + if( mbBuiltin ) + { + rStrm.Ignore( 1 ); // category + rStrm >> mnBuiltinId >> mnLevel; + } + } } - - return *mpPattern; } -ScStyleSheet* XclImpXF::CreateStyleSheet() +ScStyleSheet* XclImpStyle::CreateStyleSheet() { - if( !mpStyleSheet && maStyleName.Len() ) // valid name implies style XF + // #i1624# #i1768# ignore unnamed user styles + if( !mpStyleSheet && (maFinalName.Len() > 0) ) { bool bCreatePattern = false; - // there may be a user-defined "Default" - test on built-in too! - bool bDefStyle = mbWasBuiltIn && (maStyleName == ScGlobal::GetRscString( STR_STYLENAME_STANDARD )); + XclImpXF* pXF = GetXFBuffer().GetXF( mnXfId ); + + bool bDefStyle = mbBuiltin && (mnBuiltinId == EXC_STYLE_NORMAL); if( bDefStyle ) { - // set all flags to true to get all items in CreatePattern() - SetAllUsedFlags( true ); + // set all flags to true to get all items in XclImpXF::CreatePattern() + if( pXF ) pXF->SetAllUsedFlags( true ); // use existing "Default" style sheet mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find( ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) ); - DBG_ASSERT( mpStyleSheet, "XclImpXF::CreateStyleSheet - Default style not found" ); + DBG_ASSERT( mpStyleSheet, "XclImpStyle::CreateStyleSheet - Default style not found" ); bCreatePattern = true; } else @@ -1256,21 +1275,28 @@ ScStyleSheet* XclImpXF::CreateStyleSheet() /* #i103281# do not create another style sheet of the same name, if it exists already. This is needed to prevent that styles pasted from clipboard get duplicated over and over. */ - mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find( maStyleName, SFX_STYLE_FAMILY_PARA ) ); + mpStyleSheet = static_cast< ScStyleSheet* >( GetStyleSheetPool().Find( maFinalName, SFX_STYLE_FAMILY_PARA ) ); if( !mpStyleSheet ) { - mpStyleSheet = &static_cast< ScStyleSheet& >( GetStyleSheetPool().Make( maStyleName, SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_USERDEF ) ); + mpStyleSheet = &static_cast< ScStyleSheet& >( GetStyleSheetPool().Make( maFinalName, SFX_STYLE_FAMILY_PARA, SFXSTYLEBIT_USERDEF ) ); bCreatePattern = true; } } // bDefStyle==true omits default pool items in CreatePattern() - if( bCreatePattern && mpStyleSheet ) - mpStyleSheet->GetItemSet().Put( CreatePattern( bDefStyle ).GetItemSet() ); + if( bCreatePattern && mpStyleSheet && pXF ) + mpStyleSheet->GetItemSet().Put( pXF->CreatePattern( bDefStyle ).GetItemSet() ); } return mpStyleSheet; } +void XclImpStyle::CreateUserStyle( const String& rFinalName ) +{ + maFinalName = rFinalName; + if( !IsBuiltin() || mbCustom ) + CreateStyleSheet(); +} + // ---------------------------------------------------------------------------- XclImpXFBuffer::XclImpXFBuffer( const XclImpRoot& rRoot ) : @@ -1281,16 +1307,9 @@ XclImpXFBuffer::XclImpXFBuffer( const XclImpRoot& rRoot ) : void XclImpXFBuffer::Initialize() { maXFList.Clear(); - maStyleXFs.clear(); - /* Reserve style names that are built-in in Calc. For BIFF4 workbooks - which contain a separate list of styles per sheet, reserve all existing - names if current sheet is not the first sheet. This will create unique - names for styles in different sheets with the same name. */ - bool bReserveAll = (GetBiff() == EXC_BIFF4) && (GetCurrScTab() > 0); - SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA ); - for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() ) - if( bReserveAll || !pStyleSheet->IsUserDefined() ) - maStyleXFs[ pStyleSheet->GetName() ] = 0; + maBuiltinStyles.Clear(); + maUserStyles.Clear(); + maStylesByXf.clear(); } void XclImpXFBuffer::ReadXF( XclImpStream& rStrm ) @@ -1298,51 +1317,15 @@ void XclImpXFBuffer::ReadXF( XclImpStream& rStrm ) XclImpXF* pXF = new XclImpXF( GetRoot() ); pXF->ReadXF( rStrm ); maXFList.Append( pXF ); - - // set the name of the "Default" cell style (always the first XF in an Excel file) - if( (GetBiff() >= EXC_BIFF3) && (maXFList.Count() == 1) ) - CalcStyleName( *pXF, EXC_STYLE_NORMAL, 0 ); } void XclImpXFBuffer::ReadStyle( XclImpStream& rStrm ) { - DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF3 ); - - sal_uInt16 nXFIndex; - rStrm >> nXFIndex; - - XclImpXF* pXF = GetXF( nXFIndex & EXC_STYLE_XFMASK ); // bits 0...11 are used for XF index - if( pXF && pXF->IsStyleXF() ) - { - if( ::get_flag( nXFIndex, EXC_STYLE_BUILTIN ) ) // built-in styles - { - sal_uInt8 nStyleId, nLevel; - rStrm >> nStyleId >> nLevel; - CalcStyleName( *pXF, nStyleId, nLevel ); - } - else // user-defined styles - { - String aStyleName; - if( GetBiff() <= EXC_BIFF5 ) - aStyleName = rStrm.ReadByteString( false ); // 8 bit length - else - aStyleName = rStrm.ReadUniString(); - - if( aStyleName.Len() > 0 ) // #i1624# #i1768# ignore unnamed styles - { - // #i103281# check if this is a new built-in style introduced in XL2007 - bool bBuiltIn = false; - if( (GetBiff() == EXC_BIFF8) && (rStrm.GetNextRecId() == EXC_ID_STYLEEXT) && rStrm.StartNextRecord() ) - { - sal_uInt8 nExtFlags; - rStrm.Ignore( 12 ); - rStrm >> nExtFlags; - bBuiltIn = ::get_flag( nExtFlags, EXC_STYLEEXT_BUILTIN ); - } - CalcStyleName( *pXF, aStyleName, bBuiltIn ); - } - } - } + XclImpStyle* pStyle = new XclImpStyle( GetRoot() ); + pStyle->ReadStyle( rStrm ); + (pStyle->IsBuiltin() ? maBuiltinStyles : maUserStyles).Append( pStyle ); + DBG_ASSERT( maStylesByXf.count( pStyle->GetXfId() ) == 0, "XclImpXFBuffer::ReadStyle - multiple styles with equal XF identifier" ); + maStylesByXf[ pStyle->GetXfId() ] = pStyle; } sal_uInt16 XclImpXFBuffer::GetFontIndex( sal_uInt16 nXFIndex ) const @@ -1356,64 +1339,104 @@ const XclImpFont* XclImpXFBuffer::GetFont( sal_uInt16 nXFIndex ) const return GetFontBuffer().GetFont( GetFontIndex( nXFIndex ) ); } -void XclImpXFBuffer::CreateUserStyles() +namespace { + +/** Functor for case-insensitive string comparison, usable in maps etc. */ +struct IgnoreCaseCompare { - for( XclImpXF* pXF = maXFList.First(); pXF; pXF = maXFList.Next() ) - pXF->CreateUserStyle(); -} + inline bool operator()( const String& rName1, const String& rName2 ) const + { return rName1.CompareIgnoreCaseToAscii( rName2 ) == COMPARE_LESS; } +}; -void XclImpXFBuffer::ApplyPattern( - SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2, - SCTAB nScTab, const XclImpXFIndex& rXFIndex ) +} // namespace + +void XclImpXFBuffer::CreateUserStyles() { - if( XclImpXF* pXF = GetXF( rXFIndex.GetXFIndex() ) ) + // calculate final names of all styles + typedef ::std::map< String, XclImpStyle*, IgnoreCaseCompare > CellStyleNameMap; + typedef ::std::vector< XclImpStyle* > XclImpStyleVector; + + CellStyleNameMap aCellStyles; + XclImpStyleVector 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 styles if + current sheet is not the first sheet (this styles buffer will be + initialized again for every new sheet). This will create unique names + for styles in different sheets with the same name. Assuming that the + BIFF4W import filter is never used to import from clipboard... */ + bool bReserveAll = (GetBiff() == EXC_BIFF4) && (GetCurrScTab() > 0); + SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA ); + String aStandardName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD ); + for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() ) + if( (pStyleSheet->GetName() != aStandardName) && (bReserveAll || !pStyleSheet->IsUserDefined()) ) + if( aCellStyles.count( pStyleSheet->GetName() ) == 0 ) + aCellStyles[ pStyleSheet->GetName() ] = 0; + + /* Calculate names of built-in styles. Store styles with reserved names + in the aConflictNameStyles list. */ + for( XclImpStyle* pStyle = maBuiltinStyles.First(); pStyle; pStyle = maBuiltinStyles.Next() ) { - // #108770# set 'Standard' number format for all Boolean cells - ULONG nForceScNumFmt = rXFIndex.IsBoolCell() ? GetNumFmtBuffer().GetStdScNumFmt() : NUMBERFORMAT_ENTRY_NOT_FOUND; - pXF->ApplyPattern( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, nForceScNumFmt ); + String aStyleName = XclTools::GetBuiltInStyleName( pStyle->GetBuiltinId(), pStyle->GetName(), pStyle->GetLevel() ); + DBG_ASSERT( bReserveAll || (aCellStyles.count( aStyleName ) == 0), + "XclImpXFBuffer::CreateUserStyles - multiple styles with equal built-in identifier" ); + if( aCellStyles.count( aStyleName ) > 0 ) + aConflictNameStyles.push_back( pStyle ); + else + aCellStyles[ aStyleName ] = pStyle; } -} -void XclImpXFBuffer::CalcStyleName( XclImpXF& rXF, const String& rStyleName, bool bBuiltIn ) -{ - DBG_ASSERT( rStyleName.Len() > 0, "XclImpXFBuffer::CalcStyleName - style name empty" ); - if( rStyleName.Len() > 0 ) + /* Calculate names of user defined styles. Store styles with reserved + names in the aConflictNameStyles list. */ + for( XclImpStyle* pStyle = maUserStyles.First(); pStyle; pStyle = maUserStyles.Next() ) { - String aStyleName = bBuiltIn ? XclTools::GetBuiltInStyleName( rStyleName ) : rStyleName; - SetStyleName( rXF, aStyleName, bBuiltIn, !bBuiltIn ); + // #i1624# #i1768# ignore unnamed user styles + if( pStyle->GetName().Len() > 0 ) + { + if( aCellStyles.count( pStyle->GetName() ) > 0 ) + aConflictNameStyles.push_back( pStyle ); + else + aCellStyles[ pStyle->GetName() ] = pStyle; + } } + + // find unused names for all styles with conflicting names + for( XclImpStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt ) + { + XclImpStyle* pStyle = *aIt; + String aUnusedName; + sal_Int32 nIndex = 0; + do + { + aUnusedName.Assign( pStyle->GetName() ).Append( ' ' ).Append( String::CreateFromInt32( ++nIndex ) ); + } + while( aCellStyles.count( aUnusedName ) > 0 ); + aCellStyles[ aUnusedName ] = pStyle; + } + + // set final names and create user-defined and modified built-in cell styles + for( CellStyleNameMap::iterator aIt = aCellStyles.begin(), aEnd = aCellStyles.end(); aIt != aEnd; ++aIt ) + if( aIt->second ) + aIt->second->CreateUserStyle( aIt->first ); } -void XclImpXFBuffer::CalcStyleName( XclImpXF& rXF, sal_uInt8 nStyleId, sal_uInt8 nLevel ) +ScStyleSheet* XclImpXFBuffer::CreateStyleSheet( sal_uInt16 nXFIndex ) { - // force creation of "Default" style - SetStyleName( rXF, XclTools::GetBuiltInStyleName( nStyleId, nLevel ), true, nStyleId == EXC_STYLE_NORMAL ); + XclImpStyleMap::iterator aIt = maStylesByXf.find( nXFIndex ); + return (aIt == maStylesByXf.end()) ? 0 : aIt->second->CreateStyleSheet(); } -void XclImpXFBuffer::SetStyleName( XclImpXF& rXF, const String& rStyleName, bool bBuiltIn, bool bForceCreate ) +void XclImpXFBuffer::ApplyPattern( + SCCOL nScCol1, SCROW nScRow1, SCCOL nScCol2, SCROW nScRow2, + SCTAB nScTab, const XclImpXFIndex& rXFIndex ) { - DBG_ASSERT( rXF.IsStyleXF(), "XclImpXFBuffer::SetStyleName - not a style XF" ); - if( rXF.IsStyleXF() ) + if( XclImpXF* pXF = GetXF( rXFIndex.GetXFIndex() ) ) { - // find an unused name - String aUnusedName( rStyleName ); - sal_Int32 nIndex = 0; - while( maStyleXFs.count( aUnusedName ) > 0 ) - aUnusedName.Assign( rStyleName ).Append( ' ' ).Append( String::CreateFromInt32( ++nIndex ) ); - - // move old style to new name, if new style is built-in - if( bBuiltIn && (aUnusedName != rStyleName) ) - { - XclImpXF*& rpXF = maStyleXFs[ aUnusedName ]; - rpXF = maStyleXFs[ rStyleName ]; - if( rpXF ) - rpXF->ChangeStyleName( aUnusedName ); - aUnusedName = rStyleName; - } - - // insert new style - maStyleXFs[ aUnusedName ] = &rXF; - rXF.SetStyleName( aUnusedName, bBuiltIn, bForceCreate ); + // #108770# set 'Standard' number format for all Boolean cells + ULONG nForceScNumFmt = rXFIndex.IsBoolCell() ? GetNumFmtBuffer().GetStdScNumFmt() : NUMBERFORMAT_ENTRY_NOT_FOUND; + pXF->ApplyPattern( nScCol1, nScRow1, nScCol2, nScRow2, nScTab, nForceScNumFmt ); } } diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx index 5e6c85b49077..b8c18eb3e7c0 100644 --- a/sc/source/filter/excel/xlformula.cxx +++ b/sc/source/filter/excel/xlformula.cxx @@ -30,18 +30,13 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - -// XXX xestream.hxx MUST be included before xlformula.hxx because of the -// redifinition of the CREATE_OUSTRING() macro, which is in oox/helper.hxx -// (indirectly included via xestream.hxx) and ../inc/ftools.hxx (indirectly -// included via xlformula.hxx) that does an undef first. Ugly. -#include "xestream.hxx" #include "xlformula.hxx" #include "compiler.hxx" #include "rangenam.hxx" #include "token.hxx" #include "tokenarray.hxx" +#include "xestream.hxx" #include "xistream.hxx" #include "xlroot.hxx" diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx index 29522f4f50ff..0b6af9da2e63 100644 --- a/sc/source/filter/excel/xlroot.cxx +++ b/sc/source/filter/excel/xlroot.cxx @@ -35,6 +35,7 @@ #include <vcl/svapp.hxx> #include <svtools/stritem.hxx> #include <svtools/languageoptions.hxx> +#include <svtools/useroptions.hxx> #include <sfx2/objsh.hxx> #include <sfx2/printer.hxx> #include <sfx2/docfile.hxx> @@ -95,6 +96,11 @@ XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium, mnScTab( 0 ), mbExport( bExport ) { + // user name + maUserName = SvtUserOptions().GetLastName(); + if( maUserName.Len() == 0 ) + maUserName = CREATE_STRING( "Calc" ); + // default script type, e.g. for empty cells switch( ScGlobal::GetDefaultScriptType() ) { diff --git a/sc/source/filter/excel/xltools.cxx b/sc/source/filter/excel/xltools.cxx index a84aaba82b90..6398e25b9be7 100644 --- a/sc/source/filter/excel/xltools.cxx +++ b/sc/source/filter/excel/xltools.cxx @@ -426,16 +426,19 @@ rtl_TextEncoding XclTools::GetTextEncoding( sal_uInt16 nCodePage ) return pEntry->meTextEnc; } -//UNUSED2008-05 sal_uInt16 XclTools::GetXclCodePage( rtl_TextEncoding eTextEnc ) -//UNUSED2008-05 { -//UNUSED2008-05 const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_TEPred( eTextEnc ) ); -//UNUSED2008-05 if( pEntry == pCodePageTableEnd ) -//UNUSED2008-05 { -//UNUSED2008-05 DBG_ERROR1( "XclTools::GetXclCodePage - unsupported text encoding: %d", eTextEnc ); -//UNUSED2008-05 return 1252; -//UNUSED2008-05 } -//UNUSED2008-05 return pEntry->mnCodePage; -//UNUSED2008-05 } +sal_uInt16 XclTools::GetXclCodePage( rtl_TextEncoding eTextEnc ) +{ + if( eTextEnc == RTL_TEXTENCODING_UNICODE ) + return 1200; // for BIFF8 + + const XclCodePageEntry* pEntry = ::std::find_if( pCodePageTable, pCodePageTableEnd, XclCodePageEntry_TEPred( eTextEnc ) ); + if( pEntry == pCodePageTableEnd ) + { + DBG_ERROR1( "XclTools::GetXclCodePage - unsupported text encoding: %d", eTextEnc ); + return 1252; + } + return pEntry->mnCodePage; +} // font names ----------------------------------------------------------------- @@ -528,17 +531,26 @@ static const sal_Char* const ppcStyleNames[] = "Followed_Hyperlink" }; -String XclTools::GetBuiltInStyleName( sal_uInt8 nStyleId, sal_uInt8 nLevel ) +String XclTools::GetBuiltInStyleName( sal_uInt8 nStyleId, const String& rName, sal_uInt8 nLevel ) { String aStyleName; if( nStyleId == EXC_STYLE_NORMAL ) // "Normal" becomes "Default" style + { aStyleName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD ); - else if( nStyleId < STATIC_TABLE_SIZE( ppcStyleNames ) ) - aStyleName.Assign( maStyleNamePrefix1 ).AppendAscii( ppcStyleNames[ nStyleId ] ); - - if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) ) - aStyleName.Append( String::CreateFromInt32( nLevel + 1 ) ); + } + else + { + aStyleName = maStyleNamePrefix1; + if( nStyleId < STATIC_TABLE_SIZE( ppcStyleNames ) ) + aStyleName.AppendAscii( ppcStyleNames[ nStyleId ] ); + else if( rName.Len() > 0 ) + aStyleName.Append( rName ); + else + aStyleName.Append( String::CreateFromInt32( nStyleId ) ); + if( (nStyleId == EXC_STYLE_ROWLEVEL) || (nStyleId == EXC_STYLE_COLLEVEL) ) + aStyleName.Append( String::CreateFromInt32( nLevel + 1 ) ); + } return aStyleName; } diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx index 568032aa317f..79607802ccdc 100644 --- a/sc/source/filter/inc/excrecds.hxx +++ b/sc/source/filter/inc/excrecds.hxx @@ -210,18 +210,6 @@ public: }; -//----------------------------------------------------- class ExcFngroupcount - - -class ExcFngroupcount : public ExcRecord -{ -private: - virtual void SaveCont( XclExpStream& rStrm ); -public: - virtual UINT16 GetNum( void ) const; - virtual sal_Size GetLen( void ) const; -}; - - //--------------------------------------------------------- class ExcDummy_00 - // INTERFACEHDR to FNGROUPCOUNT (see excrecds.cxx) diff --git a/sc/source/filter/inc/ftools.hxx b/sc/source/filter/inc/ftools.hxx index 393775e721f7..5fd338a73bb5 100644 --- a/sc/source/filter/inc/ftools.hxx +++ b/sc/source/filter/inc/ftools.hxx @@ -38,6 +38,7 @@ #include <tools/string.hxx> #include <tools/list.hxx> #include <tools/debug.hxx> +#include <oox/helper/helper.hxx> #include "filter.hxx" #include "scdllapi.h" @@ -50,9 +51,6 @@ /** Expands to a temporary String, created from an ASCII character array. */ #define CREATE_STRING( ascii ) String( RTL_CONSTASCII_USTRINGPARAM( ascii ) ) -/** Expands to a temporary ::rtl::OUString, created from an ASCII character array. */ -#undef CREATE_OUSTRING -#define CREATE_OUSTRING( ascii ) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ascii ) ) // items and item sets -------------------------------------------------------- diff --git a/sc/source/filter/inc/imp_op.hxx b/sc/source/filter/inc/imp_op.hxx index ab5513ead1ed..fa0e6b7f5074 100644 --- a/sc/source/filter/inc/imp_op.hxx +++ b/sc/source/filter/inc/imp_op.hxx @@ -99,6 +99,8 @@ protected: XclImpStream maStrm; // input stream XclImpStream& aIn; // input stream + ScfUInt32Vec maSheetOffsets; + NameBuffer* pExtNameBuff; // ... externe Namen (Ind.-Basis=1) ExcelToSc* pFormConv; // Formel-Konverter diff --git a/sc/source/filter/inc/root.hxx b/sc/source/filter/inc/root.hxx index 3aa94ca542b1..ffff5dd9ff94 100644 --- a/sc/source/filter/inc/root.hxx +++ b/sc/source/filter/inc/root.hxx @@ -67,7 +67,6 @@ struct RootData // -> Inkarnation jeweils im ImportExcel-Objekt! { BiffTyp eDateiTyp; // feine Differenzierung ExtSheetBuffer* pExtSheetBuff; - NameBuffer* pTabNameBuff; ShrfmlaBuffer* pShrfmlaBuff; ExtNameBuff* pExtNameBuff; ExcelToSc* pFmlaConverter; diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx index 649a7bd02702..ef97a60a8a8e 100644 --- a/sc/source/filter/inc/xcl97rec.hxx +++ b/sc/source/filter/inc/xcl97rec.hxx @@ -412,7 +412,7 @@ private: sal_Size nRecLen; XclExpString sName; XclExpString sComment; - static XclExpString sUsername; + XclExpString sUserName; UINT8 nProtected; inline ExcEScenarioCell* _First() { return (ExcEScenarioCell*) List::First(); } @@ -424,7 +424,7 @@ private: protected: public: - ExcEScenario( ScDocument& rDoc, SCTAB nTab ); + ExcEScenario( const XclExpRoot& rRoot, SCTAB nTab ); virtual ~ExcEScenario(); virtual UINT16 GetNum() const; @@ -450,7 +450,7 @@ private: protected: public: - ExcEScenarioManager( ScDocument& rDoc, SCTAB nTab ); + ExcEScenarioManager( const XclExpRoot& rRoot, SCTAB nTab ); virtual ~ExcEScenarioManager(); virtual void Save( XclExpStream& rStrm ); @@ -558,53 +558,14 @@ private: // ============================================================================ -class XclExpFnGroupCount : public XclExpRecord -{ -public: - explicit XclExpFnGroupCount(); - virtual ~XclExpFnGroupCount(); - -private: - virtual void WriteBody( XclExpStream& rStrm ); -}; - -// ============================================================================ - /** Beginning of User Interface Records */ -class XclExpInterfaceHdr : public XclExpRecord +class XclExpInterfaceHdr : public XclExpUInt16Record { public: - explicit XclExpInterfaceHdr(); - virtual ~XclExpInterfaceHdr(); + explicit XclExpInterfaceHdr( sal_uInt16 nCodePage ); private: - virtual void WriteBody( XclExpStream& rStrm ); -}; - -// ============================================================================ - -/** Beginning of User Interface Records */ -class XclExpInterfaceEnd : public XclExpRecord -{ -public: - explicit XclExpInterfaceEnd(); - virtual ~XclExpInterfaceEnd(); - -private: - virtual void WriteBody( XclExpStream& rStrm ); -}; - -// ============================================================================ - -/** ADDMENU/DELMENU Record Group Count */ -class XclExpMMS : public XclExpRecord -{ -public: - explicit XclExpMMS(); - virtual ~XclExpMMS(); - -private: - virtual void WriteBody( XclExpStream& rStrm ); + virtual void WriteBody( XclExpStream& rStrm ); }; // ============================================================================ @@ -623,26 +584,19 @@ private: // ============================================================================ -class XclExpCodePage : public XclExpRecord +class XclExpFileSharing : public XclExpRecord { public: - explicit XclExpCodePage(); - virtual ~XclExpCodePage(); - -private: - virtual void WriteBody( XclExpStream& rStrm ); -}; + explicit XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash ); -// ============================================================================ + virtual void Save( XclExpStream& rStrm ); -class XclExpDSF : public XclExpRecord -{ -public: - explicit XclExpDSF(); - virtual ~XclExpDSF(); +private: + virtual void WriteBody( XclExpStream& rStrm ); private: - virtual void WriteBody( XclExpStream& rStrm ); + XclExpString maUserName; + sal_uInt16 mnPasswordHash; }; // ============================================================================ @@ -671,19 +625,6 @@ private: // ============================================================================ -/** What's this record for? It is a zero-byte record. */ -class XclExpExcel9File : public XclExpRecord -{ -public: - explicit XclExpExcel9File(); - virtual ~XclExpExcel9File(); - -private: - virtual void WriteBody( XclExpStream& rStrm ); -}; - -// ============================================================================ - class XclExpRecalcId : public XclExpDummyRecord { public: diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx index 3ee461f163fe..bbc1cc04fde5 100644 --- a/sc/source/filter/inc/xistream.hxx +++ b/sc/source/filter/inc/xistream.hxx @@ -269,6 +269,10 @@ public: CONTINUE usage is switched on. @return false = no record found (end of stream). */ bool StartNextRecord(); + /** Sets stream pointer to the start of the record content for the record + at the passed absolute stream position. + @return false = no record found (end of stream). */ + bool StartNextRecord( sal_Size nNextRecPos ); /** Sets stream pointer to begin of record content. @param bContLookup Automatic CONTINUE lookup on/off. In difference to other stream settings, this setting is persistent until next call of diff --git a/sc/source/filter/inc/xistyle.hxx b/sc/source/filter/inc/xistyle.hxx index 2fe3a6ecbc15..a67458366057 100644 --- a/sc/source/filter/inc/xistyle.hxx +++ b/sc/source/filter/inc/xistyle.hxx @@ -397,19 +397,14 @@ public: /** Reads an XF record. */ void ReadXF( XclImpStream& rStrm ); - /** Sets the style name of this XF, if it is a style XF. */ - void SetStyleName( const String& rStyleName, bool bBuiltIn, bool bForceCreate ); - /** Changes the style name of this XF, if it is a style XF. */ - void ChangeStyleName( const String& rStyleName ); - /** Returns the style name of this XF, if it is a style XF. */ - inline const String& GetStyleName() const { return maStyleName; } - inline sal_uInt8 GetHorAlign() const { return maAlignment.mnHorAlign; } inline sal_uInt8 GetVerAlign() const { return maAlignment.mnVerAlign; } inline sal_uInt16 GetFontIndex() const { return mnXclFont; } - /** Creates the Calc style sheet, if this is a user-defined style. */ - void CreateUserStyle(); + /** Creates a Calc item set containing an item set with all cell properties. + @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. + @return A read-only reference to the item set stored internally. */ + const ScPatternAttr& CreatePattern( bool bSkipPoolDefs = false ); /** Inserts all formatting attributes to the specified area in the Calc document. @param nForcedNumFmt If not set to NUMBERFORMAT_ENTRY_NOT_FOUND, it will overwrite @@ -434,20 +429,10 @@ private: /** Sets own "attribute used" flags, if attributes are different from passed parent XF. */ void UpdateUsedFlags( const XclImpXF& rParentXF ); - /** Creates a Calc item set containing an item set with all cell properties. - @param bSkipPoolDefs true = Do not put items equal to pool default; false = Put all items. - @return A read-only reference to the item set stored internally. */ - const ScPatternAttr& CreatePattern( bool bSkipPoolDefs = false ); - /** Creates a cell style sheet and inserts it into the Calc document. - @descr Creates a style sheet only for style XFs with a valid style name. - @return The pointer to the cell style sheet, or 0, if there is no style sheet. */ - ScStyleSheet* CreateStyleSheet(); - private: typedef ::std::auto_ptr< ScPatternAttr > ScPatternAttrPtr; ScPatternAttrPtr mpPattern; /// Calc item set. - String maStyleName; /// Name of the style sheet. ScStyleSheet* mpStyleSheet; /// Calc cell style sheet. XclImpCellProt maProtection; /// Cell protection flags. @@ -456,9 +441,42 @@ private: XclImpCellArea maArea; /// Background area style. sal_uInt16 mnXclNumFmt; /// Index to number format. sal_uInt16 mnXclFont; /// Index to font record. +}; + +// ---------------------------------------------------------------------------- - bool mbWasBuiltIn; /// true = XF was an Excel built-in style. - bool mbForceCreate; /// true = Force creation of style sheet. +/** Contains all data of a cell style associated with an XF record. */ +class XclImpStyle : protected XclImpRoot +{ +public: + explicit XclImpStyle( const XclImpRoot& rRoot ); + + /** Reads a STYLE record. */ + void ReadStyle( XclImpStream& rStrm ); + + inline const String& GetName() const { return maName; } + inline sal_uInt16 GetXfId() const { return mnXfId; } + inline bool IsBuiltin() const { return mbBuiltin && (mnBuiltinId != EXC_STYLE_USERDEF); } + inline sal_uInt8 GetBuiltinId() const { return mnBuiltinId; } + inline sal_uInt8 GetLevel() const { return mnLevel; } + + /** Creates a cell style sheet and inserts it into the Calc document. + @return The pointer to the cell style sheet, or 0, if there is no style sheet. */ + ScStyleSheet* CreateStyleSheet(); + /** Creates the Calc style sheet, if this is a user-defined style. */ + void CreateUserStyle( const String& rFinalName ); + +private: + String maName; /// Cell style name. + sal_uInt16 mnXfId; /// Formatting for this cell style. + sal_uInt8 mnBuiltinId; /// Identifier for builtin styles. + sal_uInt8 mnLevel; /// Level for builtin column/row styles. + bool mbBuiltin; /// True = builtin style. + bool mbCustom; /// True = customized builtin style. + bool mbHidden; /// True = style not visible in GUI. + + String maFinalName; /// Final name used in the Calc document. + ScStyleSheet* mpStyleSheet; /// Calc cell style sheet. }; // ---------------------------------------------------------------------------- @@ -489,6 +507,9 @@ public: /** Creates all user defined style sheets. */ void CreateUserStyles(); + /** Creates a cell style sheet of the passed XF and inserts it into the Calc document. + @return The pointer to the cell style sheet, or 0, if there is no style sheet. */ + ScStyleSheet* CreateStyleSheet( sal_uInt16 nXFIndex ); /** Inserts formatting attributes from an XF to the specified area in the Calc document. @param nForcedNumFmt If not set to NUMBERFORMAT_ENTRY_NOT_FOUND, it will overwrite @@ -499,15 +520,13 @@ public: SCTAB nScTab, const XclImpXFIndex& rXFIndex ); private: - void CalcStyleName( XclImpXF& rXF, const String& rStyleName, bool bBuiltIn ); - void CalcStyleName( XclImpXF& rXF, sal_uInt8 nStyleId, sal_uInt8 nLevel ); - void SetStyleName( XclImpXF& rXF, const String& rStyleName, bool bBuiltIn, bool bForceCreate ); - -private: - typedef ::std::map< String, XclImpXF* > XclImpStyleXFMap; + typedef ScfDelList< XclImpStyle > XclImpStyleList; + typedef ::std::map< sal_uInt16, XclImpStyle* > XclImpStyleMap; ScfDelList< XclImpXF > maXFList; /// List of contents of all XF record. - XclImpStyleXFMap maStyleXFs; /// Maps style names to style XF records. + XclImpStyleList maBuiltinStyles; /// List of built-in cell styles. + XclImpStyleList maUserStyles; /// List of user defined cell styles. + XclImpStyleMap maStylesByXf; /// Maps XF records to cell styles. }; // Buffer for XF indexes in cells ============================================= diff --git a/sc/source/filter/inc/xlconst.hxx b/sc/source/filter/inc/xlconst.hxx index eebaa76e4702..eeb3fb3982b9 100644 --- a/sc/source/filter/inc/xlconst.hxx +++ b/sc/source/filter/inc/xlconst.hxx @@ -205,6 +205,10 @@ const sal_uInt16 EXC_WSBOOL_FITTOPAGE = 0x0100; const sal_uInt16 EXC_WSBOOL_DEFAULTFLAGS = 0x04C1; +// (0x0086) WRITEPROT --------------------------------------------------------- + +const sal_uInt16 EXC_ID_WRITEPROT = 0x0086; + // (0x008C) COUNTRY ----------------------------------------------------------- const sal_uInt16 EXC_ID_COUNTRY = 0x008C; @@ -213,6 +217,10 @@ const sal_uInt16 EXC_ID_COUNTRY = 0x008C; const sal_uInt16 EXC_ID_FILTERMODE = 0x009B; +// (0x009C) FNGROUPCOUNT ------------------------------------------------------ + +const sal_uInt16 EXC_ID_FNGROUPCOUNT = 0x009C; + // (0x009D) AUTOFILTERINFO ---------------------------------------------------- const sal_uInt16 EXC_ID_AUTOFILTERINFO = 0x009D; @@ -221,15 +229,34 @@ const sal_uInt16 EXC_ID_AUTOFILTERINFO = 0x009D; const sal_uInt16 EXC_ID_AUTOFILTER = 0x009E; +// (0x00BF, 0x00C0, 0x00C1) TOOLBARHDR, TOOLBAREND, MMS ----------------------- + +const sal_uInt16 EXC_ID_TOOLBARHDR = 0x00BF; +const sal_uInt16 EXC_ID_TOOLBAREND = 0x00C0; +const sal_uInt16 EXC_ID_MMS = 0x00C1; + +// (0x00E1, 0x00E2) INTERFACEHDR, INTERFACEEND -------------------------------- + +const sal_uInt16 EXC_ID_INTERFACEHDR = 0x00E1; +const sal_uInt16 EXC_ID_INTERFACEEND = 0x00E2; + // (0x0160) USESELFS ---------------------------------------------------------- const sal_uInt16 EXC_ID_USESELFS = 0x0160; +// (0x0161) DSF --------------------------------------------------------------- + +const sal_uInt16 EXC_ID_DSF = 0x0161; + // (0x01AA,0x01AB) USERSVIEWBEGIN, USERSVIEWEND ------------------------------- const sal_uInt16 EXC_ID_USERSVIEWBEGIN = 0x01AA; const sal_uInt16 EXC_ID_USERSVIEWEND = 0x01AB; +// (0x01C0) XL9FILE -------------------------------------------------------- + +const sal_uInt16 EXC_ID_XL9FILE = 0x01C0; + // (0x8xx) Future records ----------------------------------------------------- /** Enumerates different header types of future records. */ diff --git a/sc/source/filter/inc/xlroot.hxx b/sc/source/filter/inc/xlroot.hxx index 8571dafcbc74..8b0873b25475 100644 --- a/sc/source/filter/inc/xlroot.hxx +++ b/sc/source/filter/inc/xlroot.hxx @@ -94,6 +94,7 @@ struct XclRootData ScDocument& mrDoc; /// The source or destination document. String maDocUrl; /// Document URL of imported/exported file. String maBasePath; /// Base path of imported/exported file (path of maDocUrl). + String maUserName; /// Current user name. const String maDefPassword; /// The default password used for stream encryption. rtl_TextEncoding meTextEnc; /// Text encoding to import/export byte strings. LanguageType meSysLang; /// System language. @@ -185,6 +186,8 @@ public: inline const String& GetDocUrl() const { return mrData.maDocUrl; } /** Returns the base path of the imported/exported file. */ inline const String& GetBasePath() const { return mrData.maBasePath; } + /** Returns the current user name. */ + inline const String& GetUserName() const { return mrData.maUserName; } /** Returns the default password used for stream encryption. */ inline const String& GetDefaultPassword() const { return mrData.maDefPassword; } diff --git a/sc/source/filter/inc/xlstyle.hxx b/sc/source/filter/inc/xlstyle.hxx index ebb22c2cb05f..9613abfc8725 100644 --- a/sc/source/filter/inc/xlstyle.hxx +++ b/sc/source/filter/inc/xlstyle.hxx @@ -247,6 +247,8 @@ const sal_uInt8 EXC_STYLE_NOLEVEL = 0xFF; /// Default value fo const sal_uInt16 EXC_ID_STYLEEXT = 0x0892; const sal_uInt8 EXC_STYLEEXT_BUILTIN = 0x01; +const sal_uInt8 EXC_STYLEEXT_HIDDEN = 0x02; +const sal_uInt8 EXC_STYLEEXT_CUSTOM = 0x04; // Structs and classes ======================================================== diff --git a/sc/source/filter/inc/xltools.hxx b/sc/source/filter/inc/xltools.hxx index d818fa9e0a89..392b0a2ae1fc 100644 --- a/sc/source/filter/inc/xltools.hxx +++ b/sc/source/filter/inc/xltools.hxx @@ -167,8 +167,8 @@ public: @return The corresponding text encoding or RTL_TEXTENCODING_DONTKNOW. */ static rtl_TextEncoding GetTextEncoding( sal_uInt16 nCodePage ); -//UNUSED2008-05 /** Returns an Excel code page from a text encoding. */ -//UNUSED2008-05 static sal_uInt16 GetXclCodePage( rtl_TextEncoding eTextEnc ); + /** Returns an Excel code page from a text encoding. */ + static sal_uInt16 GetXclCodePage( rtl_TextEncoding eTextEnc ); // font names ------------------------------------------------------------- @@ -194,9 +194,10 @@ public: /** Returns the specified built-in cell style name. @param nStyleId The identifier of the built-in style. + @param rName Default name for unknown styles. @param nLevel The zero-based outline level for RowLevel and ColLevel styles. @return The style name or an empty string, if the parameters are not valid. */ - static String GetBuiltInStyleName( sal_uInt8 nStyleId, sal_uInt8 nLevel ); + static String GetBuiltInStyleName( sal_uInt8 nStyleId, const String& rName, sal_uInt8 nLevel ); /** Returns the passed style name with a special built-in prefix. */ static String GetBuiltInStyleName( const String& rStyleName ); /** Returns true, if the passed string is a name of an Excel built-in style. diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index ac71dbb01fbb..608b13c49ac3 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -65,7 +65,6 @@ #include <svx/eeitem.hxx> #include <svx/msoleexp.hxx> -#include <svtools/useroptions.hxx> #include <unotools/localedatawrapper.hxx> #include <stdio.h> @@ -1033,15 +1032,14 @@ void ExcEScenarioCell::SaveXml( XclExpXmlStream& rStrm ) -XclExpString ExcEScenario::sUsername; - -ExcEScenario::ExcEScenario( ScDocument& rDoc, SCTAB nTab ) +ExcEScenario::ExcEScenario( const XclExpRoot& rRoot, SCTAB nTab ) { String sTmpName; String sTmpComm; Color aDummyCol; USHORT nFlags; + ScDocument& rDoc = rRoot.GetDoc(); rDoc.GetName( nTab, sTmpName ); sName.Assign( sTmpName, EXC_STR_8BITLENGTH ); nRecLen = 8 + sName.GetBufferSize(); @@ -1052,14 +1050,8 @@ ExcEScenario::ExcEScenario( ScDocument& rDoc, SCTAB nTab ) nRecLen += sComment.GetSize(); nProtected = (nFlags & SC_SCENARIO_PROTECT) ? 1 : 0; - if( !sUsername.Len() ) - { - SvtUserOptions aUserOpt; - sUsername.Assign( aUserOpt.GetLastName(), EXC_STR_DEFAULT, 255 ); - } - if( !sUsername.Len() ) - sUsername.Assign( String::CreateFromAscii( "SC" ) ); - nRecLen += sUsername.GetSize(); + sUserName.Assign( rRoot.GetUserName(), EXC_STR_DEFAULT, 255 ); + nRecLen += sUserName.GetSize(); const ScRangeList* pRList = rDoc.GetScenarioRanges( nTab ); if( !pRList ) @@ -1118,11 +1110,11 @@ void ExcEScenario::SaveCont( XclExpStream& rStrm ) << (UINT8) 0 // fHidden << (UINT8) sName.Len() // length of scen name << (UINT8) sComment.Len() // length of comment - << (UINT8) sUsername.Len(); // length of user name + << (UINT8) sUserName.Len(); // length of user name sName.WriteFlagField( rStrm ); sName.WriteBuffer( rStrm ); - rStrm << sUsername; + rStrm << sUserName; if( sComment.Len() ) rStrm << sComment; @@ -1154,7 +1146,7 @@ void ExcEScenario::SaveXml( XclExpXmlStream& rStrm ) XML_locked, XclXmlUtils::ToPsz( nProtected ), // OOXTODO: XML_hidden, XML_count, OString::valueOf( (sal_Int32) List::Count() ).getStr(), - XML_user, XESTRING_TO_PSZ( sUsername ), + XML_user, XESTRING_TO_PSZ( sUserName ), XML_comment, XESTRING_TO_PSZ( sComment ), FSEND ); @@ -1167,9 +1159,10 @@ void ExcEScenario::SaveXml( XclExpXmlStream& rStrm ) -ExcEScenarioManager::ExcEScenarioManager( ScDocument& rDoc, SCTAB nTab ) : +ExcEScenarioManager::ExcEScenarioManager( const XclExpRoot& rRoot, SCTAB nTab ) : nActive( 0 ) { + ScDocument& rDoc = rRoot.GetDoc(); if( rDoc.IsScenario( nTab ) ) return; @@ -1178,7 +1171,7 @@ ExcEScenarioManager::ExcEScenarioManager( ScDocument& rDoc, SCTAB nTab ) : while( rDoc.IsScenario( nNewTab ) ) { - Append( new ExcEScenario( rDoc, nNewTab ) ); + Append( new ExcEScenario( rRoot, nNewTab ) ); if( rDoc.IsActiveScenario( nNewTab ) ) nActive = static_cast<sal_uInt16>(nNewTab - nFirstTab); @@ -1453,67 +1446,15 @@ void XclExpFilePass::WriteBody( XclExpStream& rStrm ) // ============================================================================ -XclExpFnGroupCount::XclExpFnGroupCount() : - XclExpRecord(0x009C, 2) -{ -} - -XclExpFnGroupCount::~XclExpFnGroupCount() -{ -} - -void XclExpFnGroupCount::WriteBody( XclExpStream& rStrm ) -{ - rStrm << static_cast<sal_uInt16>(14); -} - -// ============================================================================ - -XclExpInterfaceHdr::XclExpInterfaceHdr() : - XclExpRecord(0x00E1, 2) -{ -} - -XclExpInterfaceHdr::~XclExpInterfaceHdr() +XclExpInterfaceHdr::XclExpInterfaceHdr( sal_uInt16 nCodePage ) : + XclExpUInt16Record( EXC_ID_INTERFACEHDR, nCodePage ) { } void XclExpInterfaceHdr::WriteBody( XclExpStream& rStrm ) { - // The value must be the same value as the CODEPAGE record. rStrm.DisableEncryption(); - rStrm << static_cast<sal_uInt16>(0x04B0); -} - -// ============================================================================ - -XclExpInterfaceEnd::XclExpInterfaceEnd() : - XclExpRecord(0x00E2, 0) -{ -} - -XclExpInterfaceEnd::~XclExpInterfaceEnd() -{ -} - -void XclExpInterfaceEnd::WriteBody( XclExpStream& /*rStrm*/ ) -{ -} - -// ============================================================================ - -XclExpMMS::XclExpMMS() : - XclExpRecord(0x00C1, 2) -{ -} - -XclExpMMS::~XclExpMMS() -{ -} - -void XclExpMMS::WriteBody( XclExpStream& rStrm ) -{ - rStrm << static_cast<sal_uInt16>(0x0000); + rStrm << GetValue(); } // ============================================================================ @@ -1552,35 +1493,25 @@ void XclExpWriteAccess::WriteBody( XclExpStream& rStrm ) // ============================================================================ -XclExpCodePage::XclExpCodePage() : - XclExpRecord(0x0042, 2) -{ -} - -XclExpCodePage::~XclExpCodePage() -{ -} - -void XclExpCodePage::WriteBody( XclExpStream& rStrm ) -{ - // 0x04B0 : UTF-16 (BIFF8) - rStrm << static_cast<sal_uInt16>(0x04B0); -} - -// ============================================================================ - -XclExpDSF::XclExpDSF() : - XclExpRecord(0x0161, 2) +XclExpFileSharing::XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash ) : + XclExpRecord( EXC_ID_FILESHARING ), + mnPasswordHash( nPasswordHash ) { + if( rRoot.GetBiff() <= EXC_BIFF5 ) + maUserName.AssignByte( rRoot.GetUserName(), rRoot.GetTextEncoding(), EXC_STR_8BITLENGTH ); + else + maUserName.Assign( rRoot.GetUserName() ); } -XclExpDSF::~XclExpDSF() +void XclExpFileSharing::Save( XclExpStream& rStrm ) { + if( mnPasswordHash != 0 ) + XclExpRecord::Save( rStrm ); } -void XclExpDSF::WriteBody( XclExpStream& rStrm ) +void XclExpFileSharing::WriteBody( XclExpStream& rStrm ) { - rStrm << static_cast<sal_uInt16>(0x0000); + rStrm << sal_uInt16( 0 ) << mnPasswordHash << maUserName; } // ============================================================================ @@ -1617,21 +1548,6 @@ void XclExpProt4RevPass::WriteBody( XclExpStream& rStrm ) // ============================================================================ -XclExpExcel9File::XclExpExcel9File() : - XclExpRecord(0x01C0, 0) -{ -} - -XclExpExcel9File::~XclExpExcel9File() -{ -} - -void XclExpExcel9File::WriteBody( XclExpStream& /*rStrm*/ ) -{ -} - -// ============================================================================ - static const sal_uInt8 nDataRecalcId[] = { 0xC1, 0x01, 0x00, 0x00, 0x54, 0x8D, 0x01, 0x00 }; diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index 5cfc833be5dd..f74e8c519fb6 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -384,11 +384,6 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData( return TokenArrayRef(); DocItem& rDoc = itrDoc->second; - RangeArrayMap::const_iterator itrRange = rDoc.maRangeArrays.find(rRange); - if (itrRange != rDoc.maRangeArrays.end()) - { - return itrRange->second; - } TableNameIndexMap::iterator itrTabId = rDoc.maTableNameIndex.find( ScGlobal::pCharClass->upper(rTabName)); @@ -410,6 +405,13 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData( // not all tables are cached. return TokenArrayRef(); + ScRange aCacheRange( nCol1, nRow1, static_cast<SCTAB>(nTabFirstId), nCol2, nRow2, static_cast<SCTAB>(nTabLastId)); + RangeArrayMap::const_iterator itrRange = rDoc.maRangeArrays.find( aCacheRange); + if (itrRange != rDoc.maRangeArrays.end()) + { + return itrRange->second; + } + TokenArrayRef pArray(new ScTokenArray); bool bFirstTab = true; for (size_t nTab = nTabFirstId; nTab <= nTabLastId; ++nTab) @@ -462,7 +464,7 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData( bFirstTab = false; } - rDoc.maRangeArrays.insert(RangeArrayMap::value_type(rRange, pArray)); + rDoc.maRangeArrays.insert( RangeArrayMap::value_type( aCacheRange, pArray)); return pArray; } @@ -545,13 +547,13 @@ void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRa return; } - size_t nTab1 = itrTabName->second; + size_t nTabFirstId = itrTabName->second; SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row(); SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col(); vector<SingleRangeData>::const_iterator itrDataBeg = rData.begin(), itrDataEnd = rData.end(); for (vector<SingleRangeData>::const_iterator itrData = itrDataBeg; itrData != itrDataEnd; ++itrData) { - size_t i = nTab1 + ::std::distance(itrDataBeg, itrData); + size_t i = nTabFirstId + ::std::distance(itrDataBeg, itrData); TableTypeRef& pTabData = rDoc.maTables[i]; if (!pTabData.get()) pTabData.reset(new Table); @@ -575,7 +577,9 @@ void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRa } } - rDoc.maRangeArrays.insert(RangeArrayMap::value_type(rRange, pArray)); + size_t nTabLastId = nTabFirstId + rRange.aEnd.Tab() - rRange.aStart.Tab(); + ScRange aCacheRange( nCol1, nRow1, static_cast<SCTAB>(nTabFirstId), nCol2, nRow2, static_cast<SCTAB>(nTabLastId)); + rDoc.maRangeArrays.insert( RangeArrayMap::value_type( aCacheRange, pArray)); } bool ScExternalRefCache::isDocInitialized(sal_uInt16 nFileId) diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx index bdf5317da1bc..07ed8709ab01 100644 --- a/sc/source/ui/unoobj/chart2uno.cxx +++ b/sc/source/ui/unoobj/chart2uno.cxx @@ -542,6 +542,14 @@ void Chart2Positioner::glueState() meGlue = GLUETYPE_COLS; return; } + // #i103540# prevent invalid vector size + if ((nC <= 0) || (nR <= 0)) + { + invalidateGlue(); + mnStartCol = 0; + mnStartRow = 0; + return; + } sal_uInt32 nCR = static_cast<sal_uInt32>(nC*nR); const sal_uInt8 nHole = 0; diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 7d551e35a392..518fe1697fe6 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -369,7 +369,8 @@ ScModelObj::ScModelObj( ScDocShell* pDocSh ) : pDocShell( pDocSh ), pPrintFuncCache( NULL ), pPrinterOptions( NULL ), - maChangesListeners( m_aMutex ) + maChangesListeners( m_aMutex ), + mnXlsWriteProtPass( 0 ) { // pDocShell may be NULL if this is the base of a ScDocOptionsObj if ( pDocShell ) @@ -1736,6 +1737,14 @@ void SAL_CALL ScModelObj::setPropertyValue( if ( aObjName.getLength() ) pDoc->RestoreChartListener( aObjName ); } + else if ( aString.EqualsAscii( "WriteProtectionPassword" ) ) + { + /* This is a hack for #160550# to preserve the write-protection + password in an XLS roundtrip. This property MUST NOT be used + for any other purpose. This property will be deleted when the + feature "Write Protection With Password" will be implemented. */ + aValue >>= mnXlsWriteProtPass; + } if ( aNewOpt != rOldOpt ) { @@ -1898,6 +1907,14 @@ uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyNa { ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL) ); } + else if ( aString.EqualsAscii( "WriteProtectionPassword" ) ) + { + /* This is a hack for #160550# to preserve the write-protection + password in an XLS roundtrip. This property MUST NOT be used + for any other purpose. This property will be deleted when the + feature "Write Protection With Password" will be implemented. */ + aRet <<= mnXlsWriteProtPass; + } } return aRet; diff --git a/scaddins/source/analysis/analysishelper.cxx b/scaddins/source/analysis/analysishelper.cxx index e241b0ab88c8..7370b1adf588 100644 --- a/scaddins/source/analysis/analysishelper.cxx +++ b/scaddins/source/analysis/analysishelper.cxx @@ -2427,7 +2427,7 @@ ConvertDataList::ConvertDataList( void ) NEWD( "in", 3.9370078740157480E01, CDC_Length ); // Inch 39,37007874015748031496062992126 NEWD( "ft", 3.2808398950131234E00, CDC_Length ); // Foot 3,2808398950131233595800524934383 NEWD( "yd", 1.0936132983377078E00, CDC_Length ); // Yard 1,0936132983377077865266841644794 - NEWD( "ang", 1.0000000000000000E10, CDC_Length ); // Angstroem + NEWDP( "ang", 1.0000000000000000E10, CDC_Length ); // Angstroem NEWD( "Pica", 2.8346456692913386E03, CDC_Length ); // Pica (1/72 Inch) 2834,6456692913385826771653543307 NEWD( "ell", 8.748906E-01, CDC_Length ); // *** Ell NEWDP( "parsec", 3.240779E-17, CDC_Length ); // *** Parsec @@ -2519,7 +2519,7 @@ ConvertDataList::ConvertDataList( void ) NEWD( "in3", 6.1023744094732284E01, CDC_Volume ); // *** Cubic Inch NEWD( "ft3", 3.5314666721488590E-02, CDC_Volume ); // *** Cubic Foot NEWD( "yd3", 1.3079506193143922E-03, CDC_Volume ); // *** Cubic Yard - NEWD( "ang3", 1.0000000000000000E27, CDC_Volume ); // *** Cubic Angstroem + NEWDP( "ang3", 1.0000000000000000E27, CDC_Volume ); // *** Cubic Angstroem NEWD( "Pica3", 2.2776990435870636E07, CDC_Volume ); // *** Cubic Pica NEWD( "barrel", 6.289811E-03, CDC_Volume ); // *** Barrel (=42gal?) NEWD( "bushel", 2.837759E-02, CDC_Volume ); // *** Bushel @@ -2557,8 +2557,8 @@ ConvertDataList::ConvertDataList( void ) // SPEED: 1 Meter per Second is... NEWDP( "m/s", 1.0000000000000000E00, CDC_Speed ); // *** Meters per Second NEWDP( "m/sec", 1.0000000000000000E00, CDC_Speed ); // *** Meters per Second also - NEWD( "m/h", 3.6000000000000000E03, CDC_Speed ); // *** Meters per Hour - NEWD( "m/hr", 3.6000000000000000E03, CDC_Speed ); // *** Meters per Hour also + NEWDP( "m/h", 3.6000000000000000E03, CDC_Speed ); // *** Meters per Hour + NEWDP( "m/hr", 3.6000000000000000E03, CDC_Speed ); // *** Meters per Hour also NEWD( "mph", 2.2369362920544023E00, CDC_Speed ); // *** Britsh Miles per Hour NEWD( "kn", 1.9438444924406048E00, CDC_Speed ); // *** Knot = Nautical Miles per Hour NEWD( "admkn", 1.9438446603753486E00, CDC_Speed ); // *** Admiralty Knot |