[ooo-build-commit] Branch 'ooo/OOO320' - 2 commits - sc/inc sc/source

Jan Holesovsky kendy at kemper.freedesktop.org
Fri Oct 9 08:00:37 PDT 2009


 sc/inc/docuno.hxx                    |    3 
 sc/source/core/data/documen3.cxx     |    3 
 sc/source/core/data/poolhelp.cxx     |   17 +
 sc/source/core/inc/poolhelp.hxx      |    4 
 sc/source/filter/excel/excdoc.cxx    |   69 ++++--
 sc/source/filter/excel/excimp8.cxx   |    6 
 sc/source/filter/excel/excrecds.cxx  |   36 ---
 sc/source/filter/excel/exctools.cxx  |    4 
 sc/source/filter/excel/impop.cxx     |   17 +
 sc/source/filter/excel/makefile.mk   |    1 
 sc/source/filter/excel/read.cxx      |   49 ++++
 sc/source/filter/excel/xeformula.cxx |   13 -
 sc/source/filter/excel/xichart.cxx   |    4 
 sc/source/filter/excel/xilink.cxx    |   40 ++-
 sc/source/filter/excel/xistream.cxx  |    6 
 sc/source/filter/excel/xistyle.cxx   |  377 ++++++++++++++++++-----------------
 sc/source/filter/excel/xlformula.cxx |    7 
 sc/source/filter/excel/xlroot.cxx    |    6 
 sc/source/filter/excel/xltools.cxx   |   44 ++--
 sc/source/filter/inc/excrecds.hxx    |   12 -
 sc/source/filter/inc/ftools.hxx      |    4 
 sc/source/filter/inc/imp_op.hxx      |    2 
 sc/source/filter/inc/root.hxx        |    1 
 sc/source/filter/inc/xcl97rec.hxx    |   85 +------
 sc/source/filter/inc/xistream.hxx    |    4 
 sc/source/filter/inc/xistyle.hxx     |   75 ++++--
 sc/source/filter/inc/xlconst.hxx     |   27 ++
 sc/source/filter/inc/xlroot.hxx      |    3 
 sc/source/filter/inc/xlstyle.hxx     |    2 
 sc/source/filter/inc/xltools.hxx     |    7 
 sc/source/filter/xcl97/xcl97rec.cxx  |  144 ++-----------
 sc/source/ui/unoobj/chart2uno.cxx    |   26 +-
 sc/source/ui/unoobj/docuno.cxx       |   21 +
 sc/source/ui/unoobj/servuno.cxx      |  131 +++++++-----
 34 files changed, 661 insertions(+), 589 deletions(-)

New commits:
commit bfc79d4d12cacc8b79878dbb0d7de9f9c56e9a10
Author: Ivo Hinkelmann <ihi at openoffice.org>
Date:   Tue Oct 6 14:49:48 2009 +0000

    CWS-TOOLING: integrate CWS calc32stopper2_OOO320
    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 at 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

diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index 1c3980e..74b867b 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -114,7 +114,8 @@ private:
     com::sun::star::uno::Reference<com::sun::star::uno::XAggregation> GetFormatter();
 
     rtl::OUString			maBuildId;
-protected: 
+    sal_Int32               mnXlsWriteProtPass;
+protected:
     const SfxItemPropertySet&   GetPropertySet() const { return aPropSet; }
 
 public:
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 970a6c3..f59a922 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 4c2a19e..f6630a1 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/poolhelp.hxx b/sc/source/core/inc/poolhelp.hxx
index c634f78..88e445c 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/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx
index 07dfe83..516308d 100644
--- a/sc/source/filter/excel/excdoc.cxx
+++ b/sc/source/filter/excel/excdoc.cxx
@@ -111,8 +111,8 @@ static void lcl_AddCalcPr( XclExpRecordList<>& aRecList, ExcTable& self )
     ScDocument& rDoc = self.GetDoc();
 
     aRecList.AppendNewRecord( new XclExpXmlStartSingleElementRecord( XML_calcPr ) );
-    // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave, 
-    //          concurrentCalc, concurrentManualCount, 
+    // OOXTODO: calcCompleted, calcId, calcMode, calcOnSave,
+    //          concurrentCalc, concurrentManualCount,
     //          forceFullCalc, fullCalcOnLoad, fullPrecision
     aRecList.AppendNewRecord( new XclCalccount( rDoc ) );
     aRecList.AppendNewRecord( new XclRefmode( rDoc ) );
@@ -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 ) );
@@ -670,7 +697,7 @@ void ExcTable::WriteXml( XclExpXmlStream& rStrm )
         rStrm.PushStream( pWorksheet );
 
         pWorksheet->startElement( XML_worksheet,
-                XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main", 
+                XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
                 FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
                 FSEND );
     }
@@ -790,8 +817,8 @@ void ExcDocument::WriteXml( SvStream& rStrm )
                 XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
                 FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
                 FSEND );
-        rWorkbook->singleElement( XML_fileVersion, 
-                XML_appName, "Calc", 
+        rWorkbook->singleElement( XML_fileVersion,
+                XML_appName, "Calc",
                 // OOXTODO: XML_codeName
                 // OOXTODO: XML_lastEdited
                 // OOXTODO: XML_lowestEdited
diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx
index 3e2bf21..36e1df9 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 d6584c7..1923bea 100644
--- a/sc/source/filter/excel/excrecds.cxx
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -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
-    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+    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,
-    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
@@ -519,7 +491,7 @@ void XclExpWsbool::SaveXml( XclExpXmlStream& rStrm )
             FSEND );
     // OOXTODO: elements XML_tabColor, XML_outlinePr
     rWorksheet->singleElement( XML_pageSetUpPr,
-            // OOXTODO: XML_autoPageBreaks, 
+            // OOXTODO: XML_autoPageBreaks,
             XML_fitToPage,  XclXmlUtils::ToPsz( GetValue() & EXC_WSBOOL_FITTOPAGE ),
             FSEND );
     rWorksheet->endElement( XML_sheetPr );
diff --git a/sc/source/filter/excel/exctools.cxx b/sc/source/filter/excel/exctools.cxx
index 37509a2..a6b1fe3 100644
--- a/sc/source/filter/excel/exctools.cxx
+++ b/sc/source/filter/excel/exctools.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -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 9d3ebe5..48c678e 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 5b483f0..4c94b07 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 5cbf7c3..c0a2a5d 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 ef15b16..849ac08 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 2d920b0..dc542a1 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 9033ecc..0026821 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 b168c43..a040f21 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 a83e203..07368f6 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 90f783d..b8c18eb 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 29522f4..0b6af9d 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 a84aaba..6398e25 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 e668114..ba8a573 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 7e71708..cef82c4 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 4b8c73e..ea286bc 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 a38c388..b69375f 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 c2b8784..b94d261 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 3ee461f..bbc1cc0 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 2fe3a6e..a674583 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 eebaa76..eeb3fb3 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 8571daf..8b0873b 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 ebb22c2..9613abf 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 d818fa9..392b0a2 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 97bd958..967a231 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);
@@ -1213,12 +1206,12 @@ void ExcEScenarioManager::SaveXml( XclExpXmlStream& rStrm )
 {
     if( ! List::Count() )
         return;
-    
+
     sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
     rWorkbook->startElement( XML_scenarios,
             XML_current,    OString::valueOf( (sal_Int32)nActive ).getStr(),
             XML_show,       OString::valueOf( (sal_Int32)nActive ).getStr(),
-            // OOXTODO: XML_sqref,      
+            // OOXTODO: XML_sqref,
             FSEND );
 
     for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
@@ -1427,8 +1420,8 @@ void XclExpFilePass::WriteBody( XclExpStream& rStrm )
         0x1a, 0x95, 0xa5, 0x75, 0xd6, 0x79, 0xcd, 0x8d };
 
 
-    static const sal_uInt8 nSalt[] = {    
-        0xa4, 0x5b, 0xf7, 0xe9, 0x9f, 0x55, 0x21, 0xc5, 
+    static const sal_uInt8 nSalt[] = {
+        0xa4, 0x5b, 0xf7, 0xe9, 0x9f, 0x55, 0x21, 0xc5,
         0xc5, 0x56, 0xa8, 0x0d, 0x39, 0x05, 0x3a, 0xb4 };
 
     // 0x0000 - neither standard nor strong encryption
@@ -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
 };
@@ -1645,7 +1561,7 @@ XclExpRecalcId::XclExpRecalcId() :
 
 static const sal_uInt8 nDataBookExt[] = {
     0x63, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+    0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x02
 };
 
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 995a7dc..51f7b80 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2008 by Sun Microsystems, Inc.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -220,7 +220,7 @@ uno::Reference< sheet::XSpreadsheetDocument > lcl_GetSpreadSheetDocument( ScDocu
 class Chart2PositionMap
 {
 public:
-    Chart2PositionMap(SCCOL nColCount, SCROW nRowCount, 
+    Chart2PositionMap(SCCOL nColCount, SCROW nRowCount,
                       bool bColAdd, bool bRowAdd, Table& rCols);
     ~Chart2PositionMap();
 
@@ -246,12 +246,12 @@ private:
     vector<FormulaToken*> maData;
 };
 
-Chart2PositionMap::Chart2PositionMap(SCCOL nColCount,  SCROW nRowCount, 
+Chart2PositionMap::Chart2PositionMap(SCCOL nColCount,  SCROW nRowCount,
                                      bool bColAdd, bool bRowAdd, Table& rCols)
 {
     // bColAdd is true when the first column serves as a row header.  Likewise,
     // when bRowAdd is true the first row serves as a column header.
-     
+
     maColHeaders.reserve(nColCount);
     maRowHeaders.reserve(nRowCount);
     maData.reserve(nColCount*nRowCount);
@@ -388,13 +388,13 @@ vector<ScSharedTokenRef>* Chart2PositionMap::getRowRanges(SCROW nRow) const
 
 // ----------------------------------------------------------------------------
 
-/** 
+/**
  * Designed to be a drop-in replacement for ScChartPositioner, in order to
  * handle external references.
  */
 class Chart2Positioner
 {
-    enum GlueType 
+    enum GlueType
     {
         GLUETYPE_NA,
         GLUETYPE_NONE,
@@ -409,7 +409,7 @@ public:
         mpPositionMap(NULL),
         meGlue(GLUETYPE_NA),
         mpDoc(pDoc),
-        mbColHeaders(false), 
+        mbColHeaders(false),
         mbRowHeaders(false),
         mbDummyUpperLeft(false)
     {
@@ -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;
@@ -672,7 +680,7 @@ void Chart2Positioner::createPositionMap()
         for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
         {
             // What's this for ???
-            sal_uInt32 nInsCol = (static_cast<sal_uInt32>(nTab) << 16) | 
+            sal_uInt32 nInsCol = (static_cast<sal_uInt32>(nTab) << 16) |
                 (bNoGlue ? 0 : static_cast<sal_uInt32>(nCol1));
             for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nInsCol)
             {
@@ -684,7 +692,7 @@ void Chart2Positioner::createPositionMap()
                         pCol = pNewRowTable.get();
                         pCols->Insert(nInsCol, pNewRowTable.release());
                         pNewRowTable.reset(new Table);
-                    }   
+                    }
                 }
                 else
                 {
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index 5dcb70f..6275edd 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -221,7 +221,8 @@ ScModelObj::ScModelObj( ScDocShell* pDocSh ) :
     aPropSet( lcl_GetDocOptPropertyMap() ),
     pDocShell( pDocSh ),
     pPrintFuncCache( NULL ),
-    maChangesListeners( m_aMutex )
+    maChangesListeners( m_aMutex ),
+    mnXlsWriteProtPass( 0 )
 {
     // pDocShell may be NULL if this is the base of a ScDocOptionsObj
     if ( pDocShell )
@@ -323,7 +324,7 @@ uno::Any SAL_CALL ScModelObj::queryInterface( const uno::Type& rType )
     SC_QUERYINTERFACE( util::XChangesNotifier )
 
     uno::Any aRet(SfxBaseModel::queryInterface( rType ));
-    if ( !aRet.hasValue() 
+    if ( !aRet.hasValue()
         && rType != ::getCppuType((uno::Reference< com::sun::star::document::XDocumentEventBroadcaster>*)0)
         && rType != ::getCppuType((uno::Reference< com::sun::star::frame::XController>*)0)
         && rType != ::getCppuType((uno::Reference< com::sun::star::frame::XFrame>*)0)
@@ -1448,6 +1449,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 )
         {
@@ -1610,6 +1619,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;
commit 6d805e50df62948b1a6eea698842a5f3da456c9e
Author: Ivo Hinkelmann <ihi at openoffice.org>
Date:   Tue Oct 6 12:37:22 2009 +0000

    CWS-TOOLING: integrate CWS sw32bf04_OOO320
    2009-09-22 Michael Stahl galobj.hxx: do not export SgaObject methods (fixes wntmsci12 build)
    2009-09-21 Michael Stahl #i105149# #i93308# svx: unofield.cxx: support field services with proper case
    2009-09-21 Michael Stahl #i105149# #i102468# sc: servuno.cxx: support field services with proper case
    2009-09-21 Michael Stahl #i105149# txtflde.cxx: support docinfo field services with proper case
    2009-09-18 Michael Stahl #i105148# fmtatr2.cxx: SwFmtMeta::Clone(): avoid assert on clone pool default
    2009-09-18 Michael Stahl #i105148# fmtatr2.cxx: SwFmtMeta::~SwFmtMeta(): check if m_pMeta != 0
    2009-09-18 Michael Stahl #i105179# unocoll.cxx: SwXFrames::getByName(): add missing breaks
    2009-09-18 Michael Stahl dbgoutsw.cxx: explicitly convert from SwNodeIndex to SwPosition
    2009-09-18 Michael Stahl galobj.hxx: export class SgaObject from svxcore, needed by unogalitem.cxx
    2009-09-17 Michael Stahl #i105149# txtflde.cxx: compare text field prefix case-insensitively
    2009-09-16 Michael Stahl #i105117# docdde.cxx: fix possible NULL dereference (patch by cmc)
    2009-09-16 Michael Stahl #i105124# docdde.cxx: fix use-after-free bug: make _FindItem member String

diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx
index 3e8b3ef..e36c88c 100644
--- a/sc/source/ui/unoobj/servuno.cxx
+++ b/sc/source/ui/unoobj/servuno.cxx
@@ -65,55 +65,71 @@ using namespace ::com::sun::star;
 
 
 //------------------------------------------------------------------------
+//
+struct ProvNamesId_Type
+{
+    const char *    pName;
+    sal_uInt16      nType;
+};
 
-static const sal_Char* __FAR_DATA aProvNames[SC_SERVICE_COUNT] =
-    {
-        "com.sun.star.sheet.Spreadsheet",			// SC_SERVICE_SHEET
-        "com.sun.star.text.TextField.URL",			// SC_SERVICE_URLFIELD
-        "com.sun.star.text.TextField.PageNumber",	// SC_SERVICE_PAGEFIELD
-        "com.sun.star.text.TextField.PageCount",	// SC_SERVICE_PAGESFIELD
-        "com.sun.star.text.TextField.Date",			// SC_SERVICE_DATEFIELD
-        "com.sun.star.text.TextField.Time",			// SC_SERVICE_TIMEFIELD
-        "com.sun.star.text.TextField.DocumentTitle",// SC_SERVICE_TITLEFIELD
-        "com.sun.star.text.TextField.FileName",		// SC_SERVICE_FILEFIELD
-        "com.sun.star.text.TextField.SheetName",	// SC_SERVICE_SHEETFIELD
-        "com.sun.star.style.CellStyle",				// SC_SERVICE_CELLSTYLE
-        "com.sun.star.style.PageStyle",				// SC_SERVICE_PAGESTYLE
-        "com.sun.star.sheet.TableAutoFormat",		// SC_SERVICE_AUTOFORMAT
-        "com.sun.star.sheet.SheetCellRanges",		// SC_SERVICE_CELLRANGES
-        "com.sun.star.drawing.GradientTable",		// SC_SERVICE_GRADTAB
-        "com.sun.star.drawing.HatchTable",			// SC_SERVICE_HATCHTAB
-        "com.sun.star.drawing.BitmapTable",			// SC_SERVICE_BITMAPTAB
-        "com.sun.star.drawing.TransparencyGradientTable",	// SC_SERVICE_TRGRADTAB
-        "com.sun.star.drawing.MarkerTable",			// SC_SERVICE_MARKERTAB
-        "com.sun.star.drawing.DashTable",			// SC_SERVICE_DASHTAB
-        "com.sun.star.text.NumberingRules",			// SC_SERVICE_NUMRULES
-        "com.sun.star.sheet.Defaults",				// SC_SERVICE_DOCDEFLTS
-        "com.sun.star.drawing.Defaults",			// SC_SERVICE_DRAWDEFLTS
-        "com.sun.star.comp.SpreadsheetSettings",	// SC_SERVICE_DOCSPRSETT
-        "com.sun.star.document.Settings",			// SC_SERVICE_DOCCONF
-        "com.sun.star.image.ImageMapRectangleObject",// SC_SERVICE_IMAP_RECT
-        "com.sun.star.image.ImageMapCircleObject",	// SC_SERVICE_IMAP_CIRC
-        "com.sun.star.image.ImageMapPolygonObject",	// SC_SERVICE_IMAP_POLY
+static const ProvNamesId_Type __FAR_DATA aProvNamesId[] =
+{
+    { "com.sun.star.sheet.Spreadsheet",                 SC_SERVICE_SHEET },
+    { "com.sun.star.text.TextField.URL",                SC_SERVICE_URLFIELD },
+    { "com.sun.star.text.TextField.PageNumber",         SC_SERVICE_PAGEFIELD },
+    { "com.sun.star.text.TextField.PageCount",          SC_SERVICE_PAGESFIELD },
+    { "com.sun.star.text.TextField.Date",               SC_SERVICE_DATEFIELD },
+    { "com.sun.star.text.TextField.Time",               SC_SERVICE_TIMEFIELD },
+    { "com.sun.star.text.TextField.DocumentTitle",      SC_SERVICE_TITLEFIELD },
+    { "com.sun.star.text.TextField.FileName",           SC_SERVICE_FILEFIELD },
+    { "com.sun.star.text.TextField.SheetName",          SC_SERVICE_SHEETFIELD },
+    { "com.sun.star.style.CellStyle",                   SC_SERVICE_CELLSTYLE },
+    { "com.sun.star.style.PageStyle",                   SC_SERVICE_PAGESTYLE },
+    { "com.sun.star.sheet.TableAutoFormat",             SC_SERVICE_AUTOFORMAT },
+    { "com.sun.star.sheet.SheetCellRanges",             SC_SERVICE_CELLRANGES },
+    { "com.sun.star.drawing.GradientTable",             SC_SERVICE_GRADTAB },
+    { "com.sun.star.drawing.HatchTable",                SC_SERVICE_HATCHTAB },
+    { "com.sun.star.drawing.BitmapTable",               SC_SERVICE_BITMAPTAB },
+    { "com.sun.star.drawing.TransparencyGradientTable", SC_SERVICE_TRGRADTAB },
+    { "com.sun.star.drawing.MarkerTable",               SC_SERVICE_MARKERTAB },
+    { "com.sun.star.drawing.DashTable",                 SC_SERVICE_DASHTAB },
+    { "com.sun.star.text.NumberingRules",               SC_SERVICE_NUMRULES },
+    { "com.sun.star.sheet.Defaults",                    SC_SERVICE_DOCDEFLTS },
+    { "com.sun.star.drawing.Defaults",                  SC_SERVICE_DRAWDEFLTS },
+    { "com.sun.star.comp.SpreadsheetSettings",          SC_SERVICE_DOCSPRSETT },
+    { "com.sun.star.document.Settings",                 SC_SERVICE_DOCCONF },
+    { "com.sun.star.image.ImageMapRectangleObject",     SC_SERVICE_IMAP_RECT },
+    { "com.sun.star.image.ImageMapCircleObject",        SC_SERVICE_IMAP_CIRC },
+    { "com.sun.star.image.ImageMapPolygonObject",       SC_SERVICE_IMAP_POLY },
 
         // #100263# Support creation of GraphicObjectResolver and EmbeddedObjectResolver
-        "com.sun.star.document.ExportGraphicObjectResolver",	// SC_SERVICE_EXPORT_GOR
-        "com.sun.star.document.ImportGraphicObjectResolver",	// SC_SERVICE_IMPORT_GOR
-        "com.sun.star.document.ExportEmbeddedObjectResolver",	// SC_SERVICE_EXPORT_EOR
-        "com.sun.star.document.ImportEmbeddedObjectResolver",	// SC_SERVICE_IMPORT_EOR
-
-        SC_SERVICENAME_VALBIND,                    // SC_SERVICE_VALBIND
-        SC_SERVICENAME_LISTCELLBIND,               // SC_SERVICE_LISTCELLBIND
-        SC_SERVICENAME_LISTSOURCE,                 // SC_SERVICE_LISTSOURCE
-        SC_SERVICENAME_CELLADDRESS,                // SC_SERVICE_CELLADDRESS
-        SC_SERVICENAME_RANGEADDRESS,                // SC_SERVICE_RANGEADDRESS
-
-        "com.sun.star.sheet.DocumentSettings",      // SC_SERVICE_SHEETDOCSET
-
-        SC_SERVICENAME_CHDATAPROV,                  // SC_SERVICE_CHDATAPROV
-        SC_SERVICENAME_FORMULAPARS,                 // SC_SERVICE_FORMULAPARS
-        SC_SERVICENAME_OPCODEMAPPER                 // SC_SERVICE_OPCODEMAPPER
-    };
+    { "com.sun.star.document.ExportGraphicObjectResolver",  SC_SERVICE_EXPORT_GOR },
+    { "com.sun.star.document.ImportGraphicObjectResolver",  SC_SERVICE_IMPORT_GOR },
+    { "com.sun.star.document.ExportEmbeddedObjectResolver", SC_SERVICE_EXPORT_EOR },
+    { "com.sun.star.document.ImportEmbeddedObjectResolver", SC_SERVICE_IMPORT_EOR },
+
+    { SC_SERVICENAME_VALBIND,               SC_SERVICE_VALBIND },
+    { SC_SERVICENAME_LISTCELLBIND,          SC_SERVICE_LISTCELLBIND },
+    { SC_SERVICENAME_LISTSOURCE,            SC_SERVICE_LISTSOURCE },
+    { SC_SERVICENAME_CELLADDRESS,           SC_SERVICE_CELLADDRESS },
+    { SC_SERVICENAME_RANGEADDRESS,          SC_SERVICE_RANGEADDRESS },
+
+    { "com.sun.star.sheet.DocumentSettings",SC_SERVICE_SHEETDOCSET },
+
+    { SC_SERVICENAME_CHDATAPROV,            SC_SERVICE_CHDATAPROV },
+    { SC_SERVICENAME_FORMULAPARS,           SC_SERVICE_FORMULAPARS },
+    { SC_SERVICENAME_OPCODEMAPPER,          SC_SERVICE_OPCODEMAPPER },
+
+    // case-correct versions of the service names (#i102468#)
+    { "com.sun.star.text.textfield.URL",                SC_SERVICE_URLFIELD },
+    { "com.sun.star.text.textfield.PageNumber",         SC_SERVICE_PAGEFIELD },
+    { "com.sun.star.text.textfield.PageCount",          SC_SERVICE_PAGESFIELD },
+    { "com.sun.star.text.textfield.Date",               SC_SERVICE_DATEFIELD },
+    { "com.sun.star.text.textfield.Time",               SC_SERVICE_TIMEFIELD },
+    { "com.sun.star.text.textfield.DocumentTitle",      SC_SERVICE_TITLEFIELD },
+    { "com.sun.star.text.textfield.FileName",           SC_SERVICE_FILEFIELD },
+    { "com.sun.star.text.textfield.SheetName",          SC_SERVICE_SHEETFIELD },
+};
 
 //
 //	old service names that were in 567 still work in createInstance,
@@ -186,11 +202,17 @@ sal_uInt16 ScServiceProvider::GetProviderType(const String& rServiceName)
 {
     if (rServiceName.Len())
     {
-        USHORT i;
-        for (i=0; i<SC_SERVICE_COUNT; i++)
-            if (rServiceName.EqualsAscii( aProvNames[i] ))
-                return i;
+        const sal_uInt16 nEntries =
+            sizeof(aProvNamesId) / sizeof(aProvNamesId[0]);
+        for (sal_uInt16 i = 0; i < nEntries; i++)
+        {
+            if (rServiceName.EqualsAscii( aProvNamesId[i].pName ))
+            {
+                return aProvNamesId[i].nType;
+            }
+        }
 
+        USHORT i;
         for (i=0; i<SC_SERVICE_COUNT; i++)
         {
             DBG_ASSERT( aOldNames[i], "ScServiceProvider::GetProviderType: no oldname => crash");
@@ -369,10 +391,13 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance(
 
 uno::Sequence<rtl::OUString> ScServiceProvider::GetAllServiceNames()
 {
-    uno::Sequence<rtl::OUString> aRet(SC_SERVICE_COUNT);
+    const sal_uInt16 nEntries = sizeof(aProvNamesId) / sizeof(aProvNamesId[0]);
+    uno::Sequence<rtl::OUString> aRet(nEntries);
     rtl::OUString* pArray = aRet.getArray();
-    for (sal_uInt16 i = 0; i < SC_SERVICE_COUNT; i++)
-        pArray[i] = rtl::OUString::createFromAscii( aProvNames[i] );
+    for (sal_uInt16 i = 0; i < nEntries; i++)
+    {
+        pArray[i] = rtl::OUString::createFromAscii( aProvNamesId[i].pName );
+    }
     return aRet;
 }
 


More information about the ooo-build-commit mailing list