Commits

Anonymous committed e8bda55

CWS-TOOLING: integrate CWS calc32stopper2
2009-10-01 12:42:16 +0200 dr r276592 : #i104992# and more typos...
2009-10-01 12:42:13 +0200 nn r276591 : #i105512# SetDocOptions: update number formatter if it already exists
2009-09-30 19:03:58 +0200 dr r276573 : #104992# oops, forgotten to skip a byte
2009-09-30 16:07:17 +0200 dr r276560 : #i103540# check valid vector size
2009-09-29 14:20:45 +0200 dr r276529 : dump some more BIFF records
2009-09-29 13:00:22 +0200 dr r276526 : dump some more BIFF records
2009-09-28 14:34:14 +0200 dr r276490 : #i104057# missing exception file
2009-09-28 10:35:42 +0200 dr r276483 : #i105325# set correct format while opening zip package
2009-09-25 19:07:32 +0200 dr r276475 : #i104992# handle cell styles built-in in Calc correctly
2009-09-25 19:06:46 +0200 dr r276474 : #i104992# handle cell styles built-in in Calc correctly
2009-09-25 17:37:28 +0200 dr r276472 : #i105219# missing include
2009-09-25 12:32:24 +0200 dr r276435 : #i10000# rebase error: renamed variable
2009-09-25 11:34:53 +0200 dr r276431 : CWS-TOOLING: rebase CWS calc32stopper2 to trunk@276429 (milestone: DEV300:m60)
2009-09-24 18:59:23 +0200 dr r276427 : 160550# preserve write-protection password in roundtrip
2009-09-24 18:54:43 +0200 dr r276426 : 160550# preserve write-protection password in roundtrip
2009-09-22 11:38:17 +0200 dr r276353 : #160550# the property has to be integer of course
2009-09-21 18:52:06 +0200 dr r276342 : #160550# new internal property WriteProtectinPassword
2009-09-21 18:22:40 +0200 dr r276340 : #i104057# load sheets substreams according to offsets in SHEET records
2009-09-21 18:11:00 +0200 dr r276338 : #i104057# load sheets substreams according to offsets in SHEET records
2009-09-17 20:07:33 +0200 dr r276255 : #i104057# BIFF5/BIFF8: order of sheet substreams may be different to sheet order, use stream offset provided in SHEET records

Comments (0)

Files changed (54)

oox/inc/oox/helper/containerhelper.hxx

                             forEach( ::boost::bind( pFunc, _1, aParam1, aParam2 ) );
                         }
 
+    /** Calls the passed functor for every contained object. Passes the key as
+        first argument and the object reference as second argument to rFunctor. */
+    template< typename FunctorType >
+    inline void         forEachWithKey( const FunctorType& rFunctor ) const
+                        {
+                            ::std::for_each( this->begin(), this->end(), ForEachFunctorWithKey< FunctorType >( rFunctor ) );
+                        }
+
+    /** Calls the passed member function of ObjType on every contained object.
+        Passes the object key as argument to the member function. */
+    template< typename FuncType >
+    inline void         forEachMemWithKey( FuncType pFunc ) const
+                        {
+                            forEachWithKey( ::boost::bind( pFunc, _2, _1 ) );
+                        }
+
+    /** Calls the passed member function of ObjType on every contained object.
+        Passes the object key as first argument to the member function. */
+    template< typename FuncType, typename ParamType >
+    inline void         forEachMemWithKey( FuncType pFunc, ParamType aParam ) const
+                        {
+                            forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam ) );
+                        }
+
+    /** Calls the passed member function of ObjType on every contained object.
+        Passes the object key as first argument to the member function. */
+    template< typename FuncType, typename ParamType1, typename ParamType2 >
+    inline void         forEachMemWithKey( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2 ) const
+                        {
+                            forEachWithKey( ::boost::bind( pFunc, _2, _1, aParam1, aParam2 ) );
+                        }
+
 private:
     template< typename FunctorType >
     struct ForEachFunctor
         inline void         operator()( const value_type& rValue ) const { if( rValue.second.get() ) mrFunctor( *rValue.second ); }
     };
 
+    template< typename FunctorType >
+    struct ForEachFunctorWithKey
+    {
+        const FunctorType&  mrFunctor;
+        inline explicit     ForEachFunctorWithKey( const FunctorType& rFunctor ) : mrFunctor( rFunctor ) {}
+        inline void         operator()( const value_type& rValue ) const { if( rValue.second.get() ) mrFunctor( rValue.first, *rValue.second ); }
+    };
+
     inline const mapped_type* getRef( key_type nKey ) const
                         {
                             typename container_type::const_iterator aIt = find( nKey );

oox/inc/oox/xls/biffhelper.hxx

 const sal_uInt16 BIFF_ID_CHPIE              = 0x1019;
 const sal_uInt16 BIFF_ID_CHPIEEXT           = 0x1061;
 const sal_uInt16 BIFF_ID_CHPIEFORMAT        = 0x100B;
+const sal_uInt16 BIFF_ID_CHPIVOTFLAGS       = 0x0859;
 const sal_uInt16 BIFF5_ID_CHPIVOTREF        = 0x1048;
 const sal_uInt16 BIFF8_ID_CHPIVOTREF        = 0x0858;
 const sal_uInt16 BIFF_ID_CHPLOTFRAME        = 0x1035;
 const sal_uInt16 BIFF_ID_WINDOW1            = 0x003D;
 const sal_uInt16 BIFF2_ID_WINDOW2           = 0x003E;
 const sal_uInt16 BIFF3_ID_WINDOW2           = 0x023E;
+const sal_uInt16 BIFF_ID_WRITEACCESS        = 0x005C;
 const sal_uInt16 BIFF_ID_XCT                = 0x0059;
 const sal_uInt16 BIFF2_ID_XF                = 0x0043;
 const sal_uInt16 BIFF3_ID_XF                = 0x0243;

oox/inc/oox/xls/biffinputstream.hxx

     /** Sets stream pointer to the start of the content of the specified record.
 
         The handle of the current record can be received and stored using the
-        function getRecHandle() for later usage with this function.
+        function getRecHandle() for later usage with this function. The record
+        handle is equivalent to the position of the underlying binary stream,
+        thus the function can be used to perform a hard seek to a specific
+        position, if it is sure that a record starts exactly at this position.
 
         @return  False = no record found (invalid handle passed).
      */

oox/inc/oox/xls/excelhandlers.hxx

      */
     BiffFragmentType    startFragment( BiffType eBiff );
 
+    /** Starts a new fragment at a specific position in the workbbok stream and
+        returns the fragment type.
+
+        The passed record handle must specify the stream position of the BOF
+        record of the fragment substream. The function will try to start the
+        next record and read the contents of the BOF record, if extant.
+
+        @return  Fragment type according to the imported BOF record.
+     */
+    BiffFragmentType    startFragment( BiffType eBiff, sal_Int64 nRecHandle );
+
     /** Skips the current fragment up to its trailing EOF record.
 
         Skips all records until next EOF record. When this function returns,
         @return  True = stream points to the EOF record of the current fragment.
      */
     bool                skipFragment();
+
+private:
+    /** Implementation helper for the startFragment() functions. */
+    BiffFragmentType    implStartFragment( BiffType eBiff );
 };
 
 // ============================================================================

oox/inc/oox/xls/stylesbuffer.hxx

     /** Final processing after import of all style settings. */
     void                finalizeImport();
 
-    /** Creates the style sheet described by the DXF. */
-    const ::rtl::OUString& createDxfStyle( sal_Int32 nDxfId );
+    /** Writes all formatting attributes to the passed property map. */
+    void                writeToPropertyMap( PropertyMap& rPropMap ) const;
+    /** Writes all formatting attributes to the passed property set. */
+    void                writeToPropertySet( PropertySet& rPropSet ) const;
 
 private:
     FontRef             mxFont;             /// Font data.
     ProtectionRef       mxProtection;       /// Protection data.
     BorderRef           mxBorder;           /// Border data.
     FillRef             mxFill;             /// Fill data.
-    ::rtl::OUString     maFinalName;        /// Final style name used in API.
 };
 
 typedef ::boost::shared_ptr< Dxf > DxfRef;
     explicit            CellStyleModel();
 
     /** Returns true, if this style is a builtin style. */
-    inline bool         isBuiltin() const { return mbBuiltin && (mnBuiltinId >= 0); }
+    bool                isBuiltin() const;
     /** Returns true, if this style represents the default document cell style. */
     bool                isDefaultStyle() const;
 };
     void                importCellStyle( RecordInputStream& rStrm );
     /** Imports style settings from a STYLE record. */
     void                importStyle( BiffInputStream& rStrm );
-    /** Sets the final style name to be used in the document. */
-    inline void         setFinalStyleName( const ::rtl::OUString& rStyleName ) { maFinalName = rStyleName; }
-
-    /** Returns true, if this style is a builtin style. */
-    inline bool         isBuiltin() const { return maModel.isBuiltin(); }
-    /** Returns true, if this style represents the default document cell style. */
-    inline bool         isDefaultStyle() const { return maModel.isDefaultStyle(); }
-    /** Returns the XF identifier for this cell style. */
-    inline sal_Int32    getXfId() const { return maModel.mnXfId; }
-    /** Calculates a readable style name according to the settings. */
-    ::rtl::OUString     calcInitialStyleName() const;
-    /** Returns the final style name used in the document. */
-    inline const ::rtl::OUString& getFinalStyleName() const { return maFinalName; }
 
     /** Creates the style sheet in the document described by this cell style object. */
     void                createCellStyle();
-    /** Creates the cell style, if it is user-defined or modified built-in. */
-    void                finalizeImport();
+    /** Stores tha passed final style name and creates the cell style, if it is
+        user-defined or modified built-in. */
+    void                finalizeImport( const ::rtl::OUString& rFinalName );
+
+    /** Returns the cell style model structure. */
+    inline const CellStyleModel& getModel() const { return maModel; }
+    /** Returns the final style name used in the document. */
+    inline const ::rtl::OUString& getFinalStyleName() const { return maFinalName; }
 
 private:
     CellStyleModel      maModel;
 
 // ============================================================================
 
+class CellStyleBuffer : public WorkbookHelper
+{
+public:
+    explicit            CellStyleBuffer( const WorkbookHelper& rHelper );
+
+    /** Appends and returns a new named cell style object. */
+    CellStyleRef        importCellStyle( const AttributeList& rAttribs );
+    /** Imports the CELLSTYLE record from the passed stream. */
+    CellStyleRef        importCellStyle( RecordInputStream& rStrm );
+    /** Imports the STYLE record from the passed stream. */
+    CellStyleRef        importStyle( BiffInputStream& rStrm );
+
+    /** Final processing after import of all style settings. */
+    void                finalizeImport();
+
+    /** Returns the XF identifier associated to the default cell style. */
+    sal_Int32           getDefaultXfId() const;
+    /** Returns the default style sheet for unused cells. */
+    ::rtl::OUString     getDefaultStyleName() const;
+    /** Creates the style sheet described by the style XF with the passed identifier. */
+    ::rtl::OUString     createCellStyle( sal_Int32 nXfId ) const;
+
+private:
+    /** Inserts the passed cell style object into the internal maps. */
+    void                insertCellStyle( CellStyleRef xCellStyle );
+    /** Creates the style sheet described by the passed cell style object. */
+    ::rtl::OUString     createCellStyle( const CellStyleRef& rxCellStyle ) const;
+
+private:
+    typedef RefVector< CellStyle >          CellStyleVector;
+    typedef RefMap< sal_Int32, CellStyle >  CellStyleXfIdMap;
+
+    CellStyleVector     maBuiltinStyles;    /// All built-in cell styles.
+    CellStyleVector     maUserStyles;       /// All user defined cell styles.
+    CellStyleXfIdMap    maStylesByXf;       /// All cell styles, mapped by XF identifier.
+    CellStyleRef        mxDefStyle;         /// Default cell style.
+};
+
+// ============================================================================
+
 class StylesBuffer : public WorkbookHelper
 {
 public:
     /** Returns the model of the default application font (used in the "Normal" cell style). */
     const FontModel&    getDefaultFontModel() const;
 
+    /** Returns the default style sheet for unused cells. */
+    ::rtl::OUString     getDefaultStyleName() const;
     /** Creates the style sheet described by the style XF with the passed identifier. */
-    const ::rtl::OUString& createCellStyle( sal_Int32 nXfId ) const;
+    ::rtl::OUString     createCellStyle( sal_Int32 nXfId ) const;
     /** Creates the style sheet described by the DXF with the passed identifier. */
-    const ::rtl::OUString& createDxfStyle( sal_Int32 nDxfId ) const;
-    /** Returns the default style sheet for unused cells. */
-    const ::rtl::OUString& getDefaultStyleName() const;
+    ::rtl::OUString     createDxfStyle( sal_Int32 nDxfId ) const;
 
     /** Writes the font attributes of the specified font data to the passed property map. */
     void                writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const;
     void                writeStyleXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const;
 
 private:
-    void                insertCellStyle( CellStyleRef xCellStyle );
-
-private:
-    typedef RefVector< Font >                       FontVec;
-    typedef RefVector< Border >                     BorderVec;
-    typedef RefVector< Fill >                       FillVec;
-    typedef RefVector< Xf >                         XfVec;
-    typedef RefVector< Dxf >                        DxfVec;
-    typedef RefMap< sal_Int32, CellStyle >          CellStyleIdMap;
-    typedef RefMap< ::rtl::OUString, CellStyle >    CellStyleNameMap;
+    typedef RefVector< Font >                           FontVector;
+    typedef RefVector< Border >                         BorderVector;
+    typedef RefVector< Fill >                           FillVector;
+    typedef RefVector< Xf >                             XfVector;
+    typedef RefVector< Dxf >                            DxfVector;
+    typedef ::std::map< sal_Int32, ::rtl::OUString >    DxfStyleMap;
 
     ColorPalette        maPalette;          /// Color palette.
-    FontVec             maFonts;            /// List of font objects.
+    FontVector          maFonts;            /// List of font objects.
     NumberFormatsBuffer maNumFmts;          /// List of all number format codes.
-    BorderVec           maBorders;          /// List of cell border objects.
-    FillVec             maFills;            /// List of cell area fill objects.
-    XfVec               maCellXfs;          /// List of cell formats.
-    XfVec               maStyleXfs;         /// List of cell styles.
-    DxfVec              maDxfs;             /// List of differential cell styles.
-    CellStyleIdMap      maCellStylesById;   /// List of named cell styles, mapped by XF identifier.
-    CellStyleNameMap    maCellStylesByName; /// List of named cell styles, mapped by name.
-    ::rtl::OUString     maDefStyleName;     /// API name of default cell style.
-    sal_Int32           mnDefStyleXf;       /// Style XF index of default cell style.
+    BorderVector        maBorders;          /// List of cell border objects.
+    FillVector          maFills;            /// List of cell area fill objects.
+    XfVector            maCellXfs;          /// List of cell formats.
+    XfVector            maStyleXfs;         /// List of cell styles.
+    CellStyleBuffer     maCellStyles;       /// All built-in and user defined cell styles.
+    DxfVector           maDxfs;             /// List of differential cell styles.
+    mutable DxfStyleMap maDxfStyles;        /// Maps DXF identifiers to Calc style sheet names.
 };
 
 // ============================================================================

oox/inc/oox/xls/workbookhelper.hxx

 
 // ============================================================================
 
+/** Functor for case-insensitive string comparison, usable in maps etc. */
+struct IgnoreCaseCompare
+{
+    bool                operator()( const ::rtl::OUString& rName1, const ::rtl::OUString& rName2 ) const;
+};
+
+// ============================================================================
+
 class WorkbookData;
 class WorkbookSettings;
 class ViewSettings;

oox/inc/oox/xls/worksheetbuffer.hxx

 {
     ::rtl::OUString     maRelId;        /// Relation identifier for the sheet substream.
     ::rtl::OUString     maName;         /// Original name of the sheet.
+    sal_Int64           mnBiffHandle;   /// BIFF record handle of the sheet substream.
     sal_Int32           mnSheetId;      /// Sheet identifier.
     sal_Int32           mnState;        /// Visibility state.
 
     sal_Int32           getWorksheetCount() const;
     /** Returns the OOX relation identifier of the specified worksheet. */
     ::rtl::OUString     getWorksheetRelId( sal_Int32 nWorksheet ) const;
+    /** Returns the BIFF record handle of the associated sheet substream. */
+    sal_Int64           getBiffRecordHandle( sal_Int32 nWorksheet ) const;
 
     /** Returns the Calc index of the specified worksheet. */
     sal_Int16           getCalcSheetIndex( sal_Int32 nWorksheet ) const;
     typedef RefVector< SheetInfo > SheetInfoVector;
     SheetInfoVector     maSheetInfos;
 
-    struct SheetNameCompare { bool operator()( const ::rtl::OUString& rName1, const ::rtl::OUString& rName2 ) const; };
-    typedef RefMap< ::rtl::OUString, SheetInfo, SheetNameCompare > SheetInfoMap;
+    typedef RefMap< ::rtl::OUString, SheetInfo, IgnoreCaseCompare > SheetInfoMap;
     SheetInfoMap        maSheetInfosByName;
 };
 

oox/source/dump/biffdumper.cxx

             if( eBiff >= BIFF8 ) dumpHex< sal_uInt16 >( "flags", "CHPIE-FLAGS" );
         break;
 
+        case BIFF_ID_CHPIVOTFLAGS:
+            dumpRepeatedRecId();
+            dumpUnused( 2 );
+            dumpHex< sal_uInt16 >( "flags", "CHPIVOTFLAGS-FLAGS" );
+        break;
+
+        case BIFF8_ID_CHPIVOTREF:
+            dumpRepeatedRecId();
+            dumpUnused( 4 );
+            dumpUniString( "ref", BIFF_STR_8BITLENGTH );
+        break;
+
         case BIFF_ID_CHPLOTGROWTH:
             dumpFix< sal_Int32 >( "horizontal-growth" );
             dumpFix< sal_Int32 >( "vertical-growth" );
                 dumpColorABGR( "grid-color" );
         break;
 
+        case BIFF_ID_WRITEACCESS:
+            dumpString( "user-name", BIFF_STR_8BITLENGTH );
+        break;
+
         case BIFF_ID_XCT:
             dumpDec< sal_uInt16 >( "crn-count" );
             if( eBiff == BIFF8 ) dumpDec< sal_Int16 >( "sheet-idx" );
     if( nStrLen != BIFF_PT_NOSTRING )
     {
         aString = (getBiff() == BIFF8) ?
-            getBiffStream().readUniString( nStrLen ) :
+            getBiffStream().readUniStringBody( nStrLen ) :
             getBiffStream().readCharArrayUC( nStrLen, getBiffData().getTextEncoding() );
         writeStringItem( rName, aString );
     }

oox/source/dump/biffdumper.ini

   0x0098=,,,FILTERMODE,,AUTOFILTERINFO,AUTOFILTER,
   0x00A8=,,,,,,SCENARIOS,SCENARIO
   0x00B0=PTDEFINITION,PTFIELD,PTFITEM,,PTROWCOLFIELDS,PTROWCOLITEMS,PTPAGEFIELDS,
-  0x00B8=DOCROUTE,RECIPNAME,,,SHAREDFMLA,MULTRK,MULTBLANK,
-  0x00C0=,MMS,ADDMENU,DELMENU,,PTDATAFIELD,PCDEFINITION,PCDFIELD
+  0x00B8=DOCROUTE,RECIPNAME,,,SHAREDFMLA,MULTRK,MULTBLANK,TOOLBARHDR
+  0x00C0=TOOLBAREND,MMS,ADDMENU,DELMENU,,PTDATAFIELD,PCDEFINITION,PCDFIELD
   0x00C8=PCITEM_INDEXLIST,PCITEM_DOUBLE,PCITEM_BOOL,PCITEM_ERROR,PCITEM_INTEGER,PCITEM_STRING,PCITEM_DATE,PCITEM_MISSING
   0x00D0=SXTBL,SXTBRGITEM,SXTBPG,OBPROJ,,PIVOTCACHE,RSTRING,DBCELL
   0x00D8=PCDFRANGEPR,PCDFDISCRETEPR,BOOKBOOL,REVERT,SXEXT|PARAMQRY,SCENPROTECT,OLESIZE,UDDESC
   0x01A8=,USERBVIEW,USERSVIEWBEGIN,USERSVIEWEND,,QSI,EXTERNALBOOK,PROT4REV
   0x01B0=CFHEADER,CFRULE,DATAVALIDATIONS,,,DCONBINAME,TXO,REFRESHALL
   0x01B8=HYPERLINK,NLRDELNAME,CODENAME,PCDFSQLTYPE,PROT4REVPASS,,DATAVALIDATION,
+  0x01C0=XL9FILE,,,,,,,
   0x0800=SCREENTIP,,,WEBQRYSETTINGS,WEBQRYTABLES,,,
   0x0850=CHFRINFO,CHFRWRAPPER,CHFRBLOCKBEGIN,CHFRBLOCKEND,,,,CHFRUNITPROPS
-  0x0858=CHPIVOTREF,,,,,,,
+  0x0858=CHPIVOTREF,CHPIVOTFLAGS,,,,,,
   0x0860=,,SHEETLAYOUT,,,,,SHEETPROTECTION
   0x0868=,,,CHFRLABELPROPS,,,,
   0x0890=,,STYLEEXT,,,,,
   0x0002=connectors
 end
 
+# CHPIVOTFLAGS ---------------------------------------------------------------
+
+flagslist=CHPIVOTFLAGS-FLAGS
+  0x0001=hide-field-captions
+end
+
 # CHRADAR, CHRADARAREA -------------------------------------------------------
 
 flagslist=CHRADAR-FLAGS

oox/source/dump/xlsbdumper.ini

   0x01C8=,,,AUTOSORTSCOPE,AUTOSORTSCOPE_END,CONDFORMATTING,CONDFORMATTING_END,CFRULE
   0x01D0=CFRULE_END,ICONSET,ICONSET_END,DATABAR,DATABAR_END,COLORSCALE,COLORSCALE_END,CFVO
   0x01D8=,COLORS,COLORS_END,RGBCOLOR,PAGEMARGINS,PRINTOPTIONS,PAGESETUP,HEADERFOOTER
-  0x01E0=HEADERFOOTER_END,,,,,SHEETFORMATPR,,
+  0x01E0=HEADERFOOTER_END,PTCHARTFORMAT,PTCHARTFORMAT_END,PTCHARTFORMATS,PTCHARTFORMATS_END,SHEETFORMATPR,,
   0x01E8=,,,,,,HYPERLINK,
   0x01F0=,,,,SCENARIOS,SCENARIOS_END,SCENARIO,SCENARIO_END
   0x01F8=INPUTCELLS,DXFS,DXFS_END,DXF,TABLESTYLES,TABLESTYLES_END,,
   0x0159=int32,dec,count
   0x017E=int32,dec,item-index
   0x01DD=uint16,hex,flags,PRINTOPTIONS-FLAGS
+  0x01E3=int32,dec,count
   0x01F9=int32,dec,count
   0x0204=int32,dec,type,VOLTYPE-TYPE
   0x020D=uint8,dec,error-code,ERRORCODES

oox/source/helper/zipstorage.cxx

 /*************************************************************************
  *
  * 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
     // create base storage object
     try
     {
-        mxStorage = ::comphelper::OStorageHelper::GetStorageFromInputStream( rxInStream, rxFactory );
+        /*  #i105325# ::comphelper::OStorageHelper::GetStorageFromInputStream()
+            cannot be used here as it will open a storage with format type
+            'PackageFormat' that will not work with OOXML packages.
+            TODO: #i105410# switch to 'OFOPXMLFormat' and use its
+            implementation of relations handling. */
+        mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(
+            ZIP_STORAGE_FORMAT_STRING, rxInStream, rxFactory );
     }
     catch( Exception& )
     {
     // create base storage object
     try
     {
-        mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OFOPXMLFormat" ) ),
-                                                                                rxStream,
-                                                                                com::sun::star::embed::ElementModes::READWRITE
-                                                                                | com::sun::star::embed::ElementModes::TRUNCATE,
-                                                                                rxFactory );
+        using namespace ::com::sun::star::embed::ElementModes;
+        mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream(
+            OFOPXML_STORAGE_FORMAT_STRING, rxStream, READWRITE | TRUNCATE, rxFactory );
     }
     catch( Exception& )
     {

oox/source/token/properties.txt

 Weight
 WhiteDay
 Width
+WriteProtectionPassword
 WritingMode
 ZoomType
 ZoomValue

oox/source/token/tokenmap.cxx

  ************************************************************************/
 
 #include "oox/token/tokenmap.hxx"
+#include <string.h>
 #include <rtl/strbuf.hxx>
 #include <rtl/string.hxx>
 #include "tokens.hxx"

oox/source/xls/excelhandlers.cxx

 
 BiffFragmentType BiffFragmentHandler::startFragment( BiffType eBiff )
 {
-    BiffFragmentType eFragment = BIFF_FRAGMENT_UNKNOWN;
-    if( mrStrm.startNextRecord() )
-    {
-        /*  #i23425# Don't rely on BOF record ID to read BOF contents, but on
-            the detected BIFF version. */
-        if( isBofRecord() )
-        {
-            // BOF is always written unencrypted
-            mrStrm.enableDecoder( false );
-            mrStrm.skip( 2 );
-            sal_uInt16 nType = mrStrm.readuInt16();
+    return mrStrm.startNextRecord() ? implStartFragment( eBiff ) : BIFF_FRAGMENT_UNKNOWN;
+}
 
-            // decide which fragment types are valid for current BIFF version
-            switch( eBiff )
-            {
-                case BIFF2: switch( nType )
-                {
-                    case BIFF_BOF_CHART:    eFragment = BIFF_FRAGMENT_EMPTYSHEET;   break;
-                    case BIFF_BOF_MACRO:    eFragment = BIFF_FRAGMENT_MACROSHEET;   break;
-                    // #i51490# Excel interprets invalid types as worksheet
-                    default:                eFragment = BIFF_FRAGMENT_WORKSHEET;
-                }
-                break;
-
-                case BIFF3: switch( nType )
-                {
-                    case BIFF_BOF_CHART:    eFragment = BIFF_FRAGMENT_EMPTYSHEET;   break;
-                    case BIFF_BOF_MACRO:    eFragment = BIFF_FRAGMENT_MACROSHEET;   break;
-                    case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN;      break;
-                    // #i51490# Excel interprets invalid types as worksheet
-                    default:                eFragment = BIFF_FRAGMENT_WORKSHEET;
-                };
-                break;
-
-                case BIFF4: switch( nType )
-                {
-                    case BIFF_BOF_CHART:    eFragment = BIFF_FRAGMENT_EMPTYSHEET;   break;
-                    case BIFF_BOF_MACRO:    eFragment = BIFF_FRAGMENT_MACROSHEET;   break;
-                    case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_WORKSPACE;    break;
-                    // #i51490# Excel interprets invalid types as worksheet
-                    default:                eFragment = BIFF_FRAGMENT_WORKSHEET;
-                };
-                break;
-
-                case BIFF5:
-                case BIFF8: switch( nType )
-                {
-                    case BIFF_BOF_GLOBALS:  eFragment = BIFF_FRAGMENT_GLOBALS;      break;
-                    case BIFF_BOF_CHART:    eFragment = BIFF_FRAGMENT_CHARTSHEET;   break;
-                    case BIFF_BOF_MACRO:    eFragment = BIFF_FRAGMENT_MACROSHEET;   break;
-                    case BIFF_BOF_MODULE:   eFragment = BIFF_FRAGMENT_MODULESHEET;  break;
-                    case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN;      break;
-                    // #i51490# Excel interprets invalid types as worksheet
-                    default:                eFragment = BIFF_FRAGMENT_WORKSHEET;
-                };
-                break;
-
-                case BIFF_UNKNOWN: break;
-            }
-        }
-    }
-    return eFragment;
+BiffFragmentType BiffFragmentHandler::startFragment( BiffType eBiff, sal_Int64 nRecHandle )
+{
+    return mrStrm.startRecordByHandle( nRecHandle ) ? implStartFragment( eBiff ) : BIFF_FRAGMENT_UNKNOWN;
 }
 
 bool BiffFragmentHandler::skipFragment()
     return !mrStrm.isEof() && (mrStrm.getRecId() == BIFF_ID_EOF);
 }
 
+BiffFragmentType BiffFragmentHandler::implStartFragment( BiffType eBiff )
+{
+    BiffFragmentType eFragment = BIFF_FRAGMENT_UNKNOWN;
+    /*  #i23425# Don't rely on BOF record ID to read BOF contents, but on
+        the detected BIFF version. */
+    if( isBofRecord() )
+    {
+        // BOF is always written unencrypted
+        mrStrm.enableDecoder( false );
+        mrStrm.skip( 2 );
+        sal_uInt16 nType = mrStrm.readuInt16();
+
+        // decide which fragment types are valid for current BIFF version
+        switch( eBiff )
+        {
+            case BIFF2: switch( nType )
+            {
+                case BIFF_BOF_CHART:    eFragment = BIFF_FRAGMENT_EMPTYSHEET;   break;
+                case BIFF_BOF_MACRO:    eFragment = BIFF_FRAGMENT_MACROSHEET;   break;
+                // #i51490# Excel interprets invalid types as worksheet
+                default:                eFragment = BIFF_FRAGMENT_WORKSHEET;
+            }
+            break;
+
+            case BIFF3: switch( nType )
+            {
+                case BIFF_BOF_CHART:    eFragment = BIFF_FRAGMENT_EMPTYSHEET;   break;
+                case BIFF_BOF_MACRO:    eFragment = BIFF_FRAGMENT_MACROSHEET;   break;
+                case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN;      break;
+                // #i51490# Excel interprets invalid types as worksheet
+                default:                eFragment = BIFF_FRAGMENT_WORKSHEET;
+            };
+            break;
+
+            case BIFF4: switch( nType )
+            {
+                case BIFF_BOF_CHART:    eFragment = BIFF_FRAGMENT_EMPTYSHEET;   break;
+                case BIFF_BOF_MACRO:    eFragment = BIFF_FRAGMENT_MACROSHEET;   break;
+                case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_WORKSPACE;    break;
+                // #i51490# Excel interprets invalid types as worksheet
+                default:                eFragment = BIFF_FRAGMENT_WORKSHEET;
+            };
+            break;
+
+            case BIFF5:
+            case BIFF8: switch( nType )
+            {
+                case BIFF_BOF_GLOBALS:  eFragment = BIFF_FRAGMENT_GLOBALS;      break;
+                case BIFF_BOF_CHART:    eFragment = BIFF_FRAGMENT_CHARTSHEET;   break;
+                case BIFF_BOF_MACRO:    eFragment = BIFF_FRAGMENT_MACROSHEET;   break;
+                case BIFF_BOF_MODULE:   eFragment = BIFF_FRAGMENT_MODULESHEET;  break;
+                case BIFF_BOF_WORKSPACE:eFragment = BIFF_FRAGMENT_UNKNOWN;      break;
+                // #i51490# Excel interprets invalid types as worksheet
+                default:                eFragment = BIFF_FRAGMENT_WORKSHEET;
+            };
+            break;
+
+            case BIFF_UNKNOWN: break;
+        }
+    }
+    return eFragment;
+}
+
 // ============================================================================
 
 BiffWorkbookFragmentBase::BiffWorkbookFragmentBase( const WorkbookHelper& rHelper, const OUString& rStrmName, bool bCloneDecoder ) :

oox/source/xls/externallinkbuffer.cxx

 
 void ExternalLinkBuffer::importExternSheet8( BiffInputStream& rStrm )
 {
-    OSL_ENSURE( getBiff() == BIFF8, "ExternalLinkBuffer::importExternSheet - wrong BIFF version" );
-    OSL_ENSURE( maRefSheets.empty(), "ExternalLinkBuffer::importExternSheet - multiple EXTERNSHEET records" );
-    maRefSheets.clear();
+    OSL_ENSURE( getBiff() == BIFF8, "ExternalLinkBuffer::importExternSheet8 - wrong BIFF version" );
+
     sal_uInt16 nRefCount;
     rStrm >> nRefCount;
-    maRefSheets.reserve( nRefCount );
-    for( sal_uInt16 nRefId = 0; !rStrm.isEof() && (nRefId < nRefCount); ++nRefId )
-    {
-        RefSheetsModel aRefSheets;
-        aRefSheets.readBiff8Data( rStrm );
-        maRefSheets.push_back( aRefSheets );
-    }
+    OSL_ENSURE( static_cast< sal_Int64 >( nRefCount * 6 ) == rStrm.getRemaining(), "ExternalLinkBuffer::importExternSheet8 - invalid count" );
+    nRefCount = static_cast< sal_uInt16 >( ::std::min< sal_Int64 >( nRefCount, rStrm.getRemaining() / 6 ) );
+
+    /*  #i104057# A weird external XLS generator writes multiple EXTERNSHEET
+        records instead of only one as expected. Surprisingly, Excel seems to
+        insert the entries of the second record before the entries of the first
+        record. */
+    maRefSheets.insert( maRefSheets.begin(), nRefCount, RefSheetsModel() );
+    for( RefSheetsModelVec::iterator aIt = maRefSheets.begin(); !rStrm.isEof() && (nRefCount > 0); --nRefCount )
+        aIt->readBiff8Data( rStrm );
 }
 
 Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const

oox/source/xls/pivottablebuffer.cxx

 {
     if( nLen == BIFF_PT_NOSTRING )
         return OUString();
-    return (rHelper.getBiff() == BIFF8) ? rStrm.readUniString( nLen ) : rStrm.readCharArrayUC( nLen, rHelper.getTextEncoding() );
+    return (rHelper.getBiff() == BIFF8) ? rStrm.readUniStringBody( nLen ) : rStrm.readCharArrayUC( nLen, rHelper.getTextEncoding() );
 }
 
 } // namespace

oox/source/xls/stylesbuffer.cxx

+
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  ************************************************************************/
 
 #include "oox/xls/stylesbuffer.hxx"
-#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
 #include <com/sun/star/container/XNameAccess.hpp>
 #include <com/sun/star/awt/FontDescriptor.hpp>
 #include <com/sun/star/awt/FontFamily.hpp>
 using ::com::sun::star::uno::UNO_QUERY;
 using ::com::sun::star::uno::UNO_QUERY_THROW;
 using ::com::sun::star::uno::UNO_SET_THROW;
-using ::com::sun::star::container::XEnumerationAccess;
-using ::com::sun::star::container::XEnumeration;
+using ::com::sun::star::container::XIndexAccess;
 using ::com::sun::star::container::XNameAccess;
 using ::com::sun::star::container::XNamed;
 using ::com::sun::star::awt::FontDescriptor;
         mxFill->finalizeImport();
 }
 
-const OUString& Dxf::createDxfStyle( sal_Int32 nDxfId )
+void Dxf::writeToPropertyMap( PropertyMap& rPropMap ) const
 {
-    if( maFinalName.getLength() == 0 )
-    {
-        maFinalName = OUStringBuffer( CREATE_OUSTRING( "ConditionalStyle_" ) ).append( nDxfId + 1 ).makeStringAndClear();
-        Reference< XStyle > xStyle = createStyleObject( maFinalName, false );
-        // write style formatting properties
-        PropertyMap aPropMap;
-        if( mxFont.get() )
-            mxFont->writeToPropertyMap( aPropMap, FONT_PROPTYPE_CELL );
-        if( mxNumFmt.get() )
-            mxNumFmt->writeToPropertyMap( aPropMap );
-        if( mxAlignment.get() )
-            mxAlignment->writeToPropertyMap( aPropMap );
-        if( mxProtection.get() )
-            mxProtection->writeToPropertyMap( aPropMap );
-        if( mxBorder.get() )
-            mxBorder->writeToPropertyMap( aPropMap );
-        if( mxFill.get() )
-            mxFill->writeToPropertyMap( aPropMap );
-        PropertySet aPropSet( xStyle );
-        aPropSet.setProperties( aPropMap );
-    }
-    return maFinalName;
+    if( mxFont.get() )
+        mxFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL );
+    if( mxNumFmt.get() )
+        mxNumFmt->writeToPropertyMap( rPropMap );
+    if( mxAlignment.get() )
+        mxAlignment->writeToPropertyMap( rPropMap );
+    if( mxProtection.get() )
+        mxProtection->writeToPropertyMap( rPropMap );
+    if( mxBorder.get() )
+        mxBorder->writeToPropertyMap( rPropMap );
+    if( mxFill.get() )
+        mxFill->writeToPropertyMap( rPropMap );
+}
+
+void Dxf::writeToPropertySet( PropertySet& rPropSet ) const
+{
+    PropertyMap aPropMap;
+    writeToPropertyMap( aPropMap );
+    rPropSet.setProperties( aPropMap );
 }
 
 // ============================================================================
 {
 }
 
+bool CellStyleModel::isBuiltin() const
+{
+    return mbBuiltin && (mnBuiltinId >= 0);
+}
+
 bool CellStyleModel::isDefaultStyle() const
 {
     return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL);
     }
 }
 
-OUString CellStyle::calcInitialStyleName() const
-{
-    return isBuiltin() ? lclGetBuiltinStyleName( maModel.mnBuiltinId, maModel.maName, maModel.mnLevel ) : maModel.maName;
-}
-
 void CellStyle::createCellStyle()
 {
     // #i1624# #i1768# ignore unnamed user styles
         // write style formatting properties
         PropertySet aPropSet( xStyle );
         getStyles().writeStyleXfToPropertySet( aPropSet, maModel.mnXfId );
-        if( !isDefaultStyle() )
+        if( !maModel.isDefaultStyle() )
             xStyle->setParentStyle( getStyles().getDefaultStyleName() );
     }
     catch( Exception& )
     }
 }
 
-void CellStyle::finalizeImport()
+void CellStyle::finalizeImport( const OUString& rFinalName )
 {
-    if( !isBuiltin() || maModel.mbCustom )
+    maFinalName = rFinalName;
+    if( !maModel.isBuiltin() || maModel.mbCustom )
         createCellStyle();
 }
 
 // ============================================================================
 
-StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) :
-    WorkbookHelper( rHelper ),
-    maPalette( rHelper ),
-    maNumFmts( rHelper ),
-    maDefStyleName( lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() ) ),
-    mnDefStyleXf( -1 )
+CellStyleBuffer::CellStyleBuffer( const WorkbookHelper& rHelper ) :
+    WorkbookHelper( rHelper )
 {
-    /*  Reserve style names that are built-in in Calc. This causes that
+}
+
+CellStyleRef CellStyleBuffer::importCellStyle( const AttributeList& rAttribs )
+{
+    CellStyleRef xCellStyle( new CellStyle( *this ) );
+    xCellStyle->importCellStyle( rAttribs );
+    insertCellStyle( xCellStyle );
+    return xCellStyle;
+}
+
+CellStyleRef CellStyleBuffer::importCellStyle( RecordInputStream& rStrm )
+{
+    CellStyleRef xCellStyle( new CellStyle( *this ) );
+    xCellStyle->importCellStyle( rStrm );
+    insertCellStyle( xCellStyle );
+    return xCellStyle;
+}
+
+CellStyleRef CellStyleBuffer::importStyle( BiffInputStream& rStrm )
+{
+    CellStyleRef xCellStyle( new CellStyle( *this ) );
+    xCellStyle->importStyle( rStrm );
+    insertCellStyle( xCellStyle );
+    return xCellStyle;
+}
+
+void CellStyleBuffer::finalizeImport()
+{
+    // calculate final names of all styles
+    typedef RefMap< OUString, CellStyle, IgnoreCaseCompare > CellStyleNameMap;
+    CellStyleNameMap aCellStyles;
+    CellStyleVector aConflictNameStyles;
+
+    /*  First, reserve style names that are built-in in Calc. This causes that
         imported cell styles get different unused names and thus do not try to
         overwrite these built-in styles. For BIFF4 workbooks (which contain a
-        separate list of cell styles per sheet), reserve all existing names if
+        separate list of cell styles per sheet), reserve all existing styles if
         current sheet is not the first sheet (this styles buffer will be
         constructed again for every new sheet). This will create unique names
-        for styles in different sheets with the same name. */
+        for styles in different sheets with the same name. Assuming that the
+        BIFF4W import filter is never used to import from clipboard... */
     bool bReserveAll = (getFilterType() == FILTER_BIFF) && (getBiff() == BIFF4) && isWorkbookFile() && (getCurrentSheetIndex() > 0);
     try
     {
-        Reference< XEnumerationAccess > xCellStylesEA( getStyleFamily( false ), UNO_QUERY_THROW );
-        Reference< XEnumeration > xCellStylesEnum( xCellStylesEA->createEnumeration(), UNO_SET_THROW );
-        while( xCellStylesEnum->hasMoreElements() )
+        // unfortunately, com.sun.star.style.StyleFamily does not implement XEnumerationAccess...
+        Reference< XIndexAccess > xStyleFamilyIA( getStyleFamily( false ), UNO_QUERY_THROW );
+        for( sal_Int32 nIndex = 0, nCount = xStyleFamilyIA->getCount(); nIndex < nCount; ++nIndex )
         {
-            Reference< XStyle > xCellStyle( xCellStylesEnum->nextElement(), UNO_QUERY_THROW );
-            if( bReserveAll || !xCellStyle->isUserDefined() )
+            Reference< XStyle > xStyle( xStyleFamilyIA->getByIndex( nIndex ), UNO_QUERY_THROW );
+            if( bReserveAll || !xStyle->isUserDefined() )
             {
-                Reference< XNamed > xCellStyleName( xCellStyle, UNO_QUERY_THROW );
+                Reference< XNamed > xStyleName( xStyle, UNO_QUERY_THROW );
                 // create an empty entry by using ::std::map<>::operator[]
-                maCellStylesByName[ xCellStyleName->getName() ];
+                aCellStyles[ xStyleName->getName() ];
             }
         }
     }
     catch( Exception& )
     {
     }
+
+    /*  Calculate names of built-in styles. Store styles with reserved names
+        in the aConflictNameStyles list. */
+    for( CellStyleVector::iterator aIt = maBuiltinStyles.begin(), aEnd = maBuiltinStyles.end(); aIt != aEnd; ++aIt )
+    {
+        const CellStyleModel& rModel = (*aIt)->getModel();
+        OUString aStyleName = lclGetBuiltinStyleName( rModel.mnBuiltinId, rModel.maName, rModel.mnLevel );
+        OSL_ENSURE( bReserveAll || (aCellStyles.count( aStyleName ) == 0),
+            "CellStyleBuffer::finalizeImport - multiple styles with equal built-in identifier" );
+        if( aCellStyles.count( aStyleName ) > 0 )
+            aConflictNameStyles.push_back( *aIt );
+        else
+            aCellStyles[ aStyleName ] = *aIt;
+    }
+
+    /*  Calculate names of user defined styles. Store styles with reserved
+        names in the aConflictNameStyles list. */
+    for( CellStyleVector::iterator aIt = maUserStyles.begin(), aEnd = maUserStyles.end(); aIt != aEnd; ++aIt )
+    {
+        const CellStyleModel& rModel = (*aIt)->getModel();
+        // #i1624# #i1768# ignore unnamed user styles
+        if( rModel.maName.getLength() > 0 )
+        {
+            if( aCellStyles.count( rModel.maName ) > 0 )
+                aConflictNameStyles.push_back( *aIt );
+            else
+                aCellStyles[ rModel.maName ] = *aIt;
+        }
+    }
+
+    // find unused names for all styles with conflicting names
+    for( CellStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt )
+    {
+        const CellStyleModel& rModel = (*aIt)->getModel();
+        OUString aUnusedName;
+        sal_Int32 nIndex = 0;
+        do
+        {
+            aUnusedName = OUStringBuffer( rModel.maName ).append( sal_Unicode( ' ' ) ).append( ++nIndex ).makeStringAndClear();
+        }
+        while( aCellStyles.count( aUnusedName ) > 0 );
+        aCellStyles[ aUnusedName ] = *aIt;
+    }
+
+    // set final names and create user-defined and modified built-in cell styles
+    aCellStyles.forEachMemWithKey( &CellStyle::finalizeImport );
+}
+
+sal_Int32 CellStyleBuffer::getDefaultXfId() const
+{
+    return mxDefStyle.get() ? mxDefStyle->getModel().mnXfId : -1;
+}
+
+OUString CellStyleBuffer::getDefaultStyleName() const
+{
+    return createCellStyle( mxDefStyle );
+}
+
+OUString CellStyleBuffer::createCellStyle( sal_Int32 nXfId ) const
+{
+    return createCellStyle( maStylesByXf.get( nXfId ) );
+}
+
+// private --------------------------------------------------------------------
+
+void CellStyleBuffer::insertCellStyle( CellStyleRef xCellStyle )
+{
+    const CellStyleModel& rModel = xCellStyle->getModel();
+    if( rModel.mnXfId >= 0 )
+    {
+        // insert into the built-in map or user defined map
+        (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle );
+
+        // insert into the XF identifier map
+        OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" );
+        maStylesByXf[ rModel.mnXfId ] = xCellStyle;
+
+        // remember default cell style
+        if( rModel.isDefaultStyle() )
+            mxDefStyle = xCellStyle;
+    }
+}
+
+OUString CellStyleBuffer::createCellStyle( const CellStyleRef& rxCellStyle ) const
+{
+    if( rxCellStyle.get() )
+    {
+        rxCellStyle->createCellStyle();
+        const OUString& rStyleName = rxCellStyle->getFinalStyleName();
+        if( rStyleName.getLength() > 0 )
+            return rStyleName;
+    }
+    // on error: fallback to default style
+    return lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() );
+}
+
+// ============================================================================
+
+StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) :
+    WorkbookHelper( rHelper ),
+    maPalette( rHelper ),
+    maNumFmts( rHelper ),
+    maCellStyles( rHelper )
+{
 }
 
 FontRef StylesBuffer::createFont( sal_Int32* opnFontId )
 
 CellStyleRef StylesBuffer::importCellStyle( const AttributeList& rAttribs )
 {
-    CellStyleRef xCellStyle( new CellStyle( *this ) );
-    xCellStyle->importCellStyle( rAttribs );
-    insertCellStyle( xCellStyle );
-    return xCellStyle;
+    return maCellStyles.importCellStyle( rAttribs );
 }
 
 void StylesBuffer::importPaletteColor( RecordInputStream& rStrm )
 
 void StylesBuffer::importCellStyle( RecordInputStream& rStrm )
 {
-    CellStyleRef xCellStyle( new CellStyle( *this ) );
-    xCellStyle->importCellStyle( rStrm );
-    insertCellStyle( xCellStyle );
+    maCellStyles.importCellStyle( rStrm );
 }
 
 void StylesBuffer::importPalette( BiffInputStream& rStrm )
 
 void StylesBuffer::importStyle( BiffInputStream& rStrm )
 {
-    CellStyleRef xCellStyle( new CellStyle( *this ) );
-    xCellStyle->importStyle( rStrm );
-    insertCellStyle( xCellStyle );
+    maCellStyles.importStyle( rStrm );
 }
 
 void StylesBuffer::finalizeImport()
         maStyleXfs.forEachMem( &Xf::finalizeImport );
     maCellXfs.forEachMem( &Xf::finalizeImport );
 
-    // conditional formatting
+    // built-in and user defined cell styles
+    maCellStyles.finalizeImport();
+
+    // differential formatting (for conditional formatting)
     maDxfs.forEachMem( &Dxf::finalizeImport );
-
-    // create the default cell style first
-    if( CellStyle* pDefStyle = maCellStylesById.get( mnDefStyleXf ).get() )
-        pDefStyle->createCellStyle();
-    // create user-defined and modified built-in cell styles
-    maCellStylesById.forEachMem( &CellStyle::finalizeImport );
 }
 
 sal_Int32 StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const
 FontRef StylesBuffer::getDefaultFont() const
 {
     FontRef xDefFont;
-    if( const Xf* pXf = getStyleXf( mnDefStyleXf ).get() )
+    if( const Xf* pXf = getStyleXf( maCellStyles.getDefaultXfId() ).get() )
         xDefFont = pXf->getFont();
     // no font from styles - try first loaded font (e.g. BIFF2)
     if( !xDefFont )
     return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel();
 }
 
-const OUString& StylesBuffer::createCellStyle( sal_Int32 nXfId ) const
+OUString StylesBuffer::getDefaultStyleName() const
 {
-    if( CellStyle* pCellStyle = maCellStylesById.get( nXfId ).get() )
+    return maCellStyles.getDefaultStyleName();
+}
+
+OUString StylesBuffer::createCellStyle( sal_Int32 nXfId ) const
+{
+    return maCellStyles.createCellStyle( nXfId );
+}
+
+OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const
+{
+    OUString& rStyleName = maDxfStyles[ nDxfId ];
+    if( rStyleName.getLength() == 0 )
     {
-        pCellStyle->createCellStyle();
-        const OUString& rStyleName = pCellStyle->getFinalStyleName();
-        if( rStyleName.getLength() > 0 )
-            return rStyleName;
+        if( Dxf* pDxf = maDxfs.get( nDxfId ).get() )
+        {
+            rStyleName = OUStringBuffer( CREATE_OUSTRING( "ConditionalStyle_" ) ).append( nDxfId + 1 ).makeStringAndClear();
+            // create the style sheet (this may change rStyleName if such a style already exists)
+            Reference< XStyle > xStyle = createStyleObject( rStyleName, false );
+            // write style formatting properties
+            PropertySet aPropSet( xStyle );
+            pDxf->writeToPropertySet( aPropSet );
+        }
+        // on error: fallback to default style
+        if( rStyleName.getLength() == 0 )
+            rStyleName = maCellStyles.getDefaultStyleName();
     }
-    // on error: fallback to default style
-    return maDefStyleName;
-}
-
-const OUString& StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const
-{
-    if( Dxf* pDxf = maDxfs.get( nDxfId ).get() )
-        return pDxf->createDxfStyle( nDxfId );
-    // on error: fallback to default style
-    return maDefStyleName;
-}
-
-const OUString& StylesBuffer::getDefaultStyleName() const
-{
-    return createCellStyle( mnDefStyleXf );
+    return rStyleName;
 }
 
 void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const
         pXf->writeToPropertySet( rPropSet );
 }
 
-void StylesBuffer::insertCellStyle( CellStyleRef xCellStyle )
-{
-    sal_Int32 nXfId = xCellStyle->getXfId();
-    OUString aStyleName = xCellStyle->calcInitialStyleName();
-    // #i1624# #i1768# ignore unnamed user styles
-    if( (nXfId >= 0) && (aStyleName.getLength() > 0) )
-    {
-        // insert into the XF identifier map
-        maCellStylesById[ nXfId ] = xCellStyle;
-
-        // find an unused name
-        OUString aUnusedName = aStyleName;
-        sal_Int32 nIndex = 0;
-        while( maCellStylesByName.count( aUnusedName ) > 0 )
-            aUnusedName = OUStringBuffer( aStyleName ).append( sal_Unicode( ' ' ) ).append( ++nIndex ).makeStringAndClear();
-
-        // move old existing style to new unused name, if new style is built-in
-        if( xCellStyle->isBuiltin() && (aStyleName != aUnusedName) )
-        {
-            CellStyleRef& rxCellStyle = maCellStylesByName[ aUnusedName ];
-            rxCellStyle = maCellStylesByName[ aStyleName ];
-            // the entry may be empty if the style name has been reserved in c'tor
-            if( rxCellStyle.get() )
-                rxCellStyle->setFinalStyleName( aUnusedName );
-            aUnusedName = aStyleName;
-        }
-
-        // insert new style
-        maCellStylesByName[ aUnusedName ] = xCellStyle;
-        xCellStyle->setFinalStyleName( aUnusedName );
-
-        // remember XF identifier of default cell style
-        if( xCellStyle->isDefaultStyle() )
-            mnDefStyleXf = nXfId;
-    }
-}
-
 // ============================================================================
 
 } // namespace xls

oox/source/xls/workbookfragment.cxx

                 // try to start a new sheet fragment
                 double fSegmentLength = getProgressBar().getFreeLength() / (nWorksheetCount - nWorksheet);
                 ISegmentProgressBarRef xSheetProgress = getProgressBar().createSegment( fSegmentLength );
-                BiffFragmentType eSheetFragment = startFragment( getBiff() );
+                BiffFragmentType eSheetFragment = startFragment( getBiff(), rWorksheets.getBiffRecordHandle( nWorksheet ) );
                 sal_Int16 nCalcSheet = rWorksheets.getCalcSheetIndex( nWorksheet );
                 bNextSheet = importSheetFragment( *xSheetProgress, eSheetFragment, nCalcSheet );
             }

oox/source/xls/workbookhelper.cxx

 
 // ============================================================================
 
+bool IgnoreCaseCompare::operator()( const OUString& rName1, const OUString& rName2 ) const
+{
+    // there is no wrapper in rtl::OUString, TODO: compare with collator
+    return ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
+        rName1.getStr(), rName1.getLength(), rName2.getStr(), rName2.getLength() ) < 0;
+}
+
+// ============================================================================
+
 class WorkbookData
 #if OSL_DEBUG_LEVEL > 0
     : public dbg::WorkbookData

oox/source/xls/workbooksettings.cxx

     // write protection
     if( maFileSharing.mbRecommendReadOnly || (maFileSharing.mnPasswordHash != 0) )
         getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "ReadOnly" ) ] <<= true;
+    if( maFileSharing.mnPasswordHash != 0 )
+        aPropSet.setProperty( PROP_WriteProtectionPassword, static_cast< sal_Int32 >( maFileSharing.mnPasswordHash ) );
 
     // calculation settings
     Date aNullDate = getNullDate();

oox/source/xls/worksheetbuffer.cxx

 // ============================================================================
 
 SheetInfoModel::SheetInfoModel() :
+    mnBiffHandle( -1 ),
     mnSheetId( -1 ),
     mnState( XML_visible )
 {
 
 void WorksheetBuffer::importSheet( BiffInputStream& rStrm )
 {
-    sal_uInt16 nState = 0;
+    SheetInfoModel aModel;
     if( getBiff() >= BIFF5 )
     {
-        rStrm.skip( 4 );
-        rStrm >> nState;
+        rStrm.enableDecoder( false );
+        aModel.mnBiffHandle = rStrm.readuInt32();
+        rStrm.enableDecoder( true );
+        sal_uInt16 nState = rStrm.readuInt16();
+        static const sal_Int32 spnStates[] = { XML_visible, XML_hidden, XML_veryHidden };
+        aModel.mnState = STATIC_ARRAY_SELECT( spnStates, nState, XML_visible );
     }
-
-    SheetInfoModel aModel;
     aModel.maName = (getBiff() == BIFF8) ?
         rStrm.readUniStringBody( rStrm.readuInt8() ) :
         rStrm.readByteStringUC( false, getTextEncoding() );
-    static const sal_Int32 spnStates[] = { XML_visible, XML_hidden, XML_veryHidden };
-    aModel.mnState = STATIC_ARRAY_SELECT( spnStates, nState, XML_visible );
     insertSheet( aModel );
 }
 
     return pSheetInfo ? pSheetInfo->maRelId : OUString();
 }
 
+sal_Int64 WorksheetBuffer::getBiffRecordHandle( sal_Int32 nWorksheet ) const
+{
+    const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get();
+    return pSheetInfo ? pSheetInfo->mnBiffHandle : -1;
+}
+
 sal_Int16 WorksheetBuffer::getCalcSheetIndex( sal_Int32 nWorksheet ) const
 {
     const SheetInfo* pSheetInfo = maSheetInfos.get( nWorksheet ).get();
     maSheetInfosByName[ lclQuoteName( rModel.maName ) ] = xSheetInfo;
 }
 
-bool WorksheetBuffer::SheetNameCompare::operator()( const OUString& rName1, const OUString& rName2 ) const
-{
-    // there is no wrapper in rtl::OUString, TODO: compare with collator
-    return ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
-        rName1.getStr(), rName1.getLength(), rName2.getStr(), rName2.getLength() ) < 0;
-}
-
 // ============================================================================
 
 } // namespace xls

sc/inc/docuno.hxx

     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:

sc/source/core/data/documen3.cxx

 
 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);
 }

sc/source/core/data/poolhelp.cxx

         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

sc/source/core/inc/poolhelp.hxx

 	mutable SfxItemPool*		pEnginePool;					// EditEnginePool
     ScDocument*         m_pSourceDoc;
 
+    void                UseDocOptions() const;
+
 public:
 				ScPoolHelper( ScDocument* pSourceDoc );
 	virtual		~ScPoolHelper();
 	SfxItemPool*		GetEditPool() const;
 	SfxItemPool*		GetEnginePool() const;
 
-    void                SetFormTableOpt(const ScDocOptions& rOpt) { aOpt = rOpt; }
+    void                SetFormTableOpt(const ScDocOptions& rOpt);
 };
 
 #endif

sc/source/filter/excel/excdoc.cxx

     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 ) );
 }
 #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 ) );
 }
 
 
 
 	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 ExcDummy_00 );
+    {
+        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()) );
+        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 XclExpInterfaceHdr );
-        Add( new XclExpMMS );
-        Add( new XclExpInterfaceEnd );
-        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() )
             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;
         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 );
     // 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 ) );
         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 );
     }
                 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

sc/source/filter/excel/excimp8.cxx

 	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 )
 	{

sc/source/filter/excel/excrecds.cxx

 /*************************************************************************
  *
  * 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
 
 //--------------------------------------------------------- class ExcDummy_00 -
 const BYTE		ExcDummy_00::pMyData[] = {
-	0xe1, 0x00, 0x00, 0x00,									// INTERFACEHDR
-	0xc1, 0x00, 0x02, 0x00, 0x00, 0x00,						// MMS
-	0xbf, 0x00, 0x00, 0x00,									// TOOLBARHDR
-	0xc0, 0x00, 0x00, 0x00,									// TOOLBAREND
-	0xe2, 0x00, 0x00, 0x00,									// INTERFACEEND
-	0x5c, 0x00, 0x20, 0x00, 0x04, 0x4d, 0x72, 0x20, 0x58,	// WRITEACCESS
+    0x5c, 0x00, 0x20, 0x00, 0x04, 'C',  'a',  'l',  'c',    // WRITEACCESS
 	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-	0x42, 0x00, 0x02, 0x00, 0xe4, 0x04,						// CODEPAGE
-	0x9c, 0x00, 0x02, 0x00, 0x0e, 0x00						// FNGROUPCOUNT
+    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
 };
 const sal_Size ExcDummy_00::nMyLen = sizeof( ExcDummy_00::pMyData );
 
 
 
 
-//----------------------------------------------------- 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
             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 );

sc/source/filter/excel/exctools.cxx

 /*************************************************************************
  *
  * 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
 {
     eDateiTyp = BiffX;
 	pExtSheetBuff = NULL;
-	pTabNameBuff = NULL;
 	pShrfmlaBuff = NULL;
 	pExtNameBuff = NULL;
     pFmlaConverter = NULL;
 RootData::~RootData()
 {
 	delete pExtSheetBuff;
-	delete pTabNameBuff;
 	delete pShrfmlaBuff;
 	delete pExtNameBuff;
     delete pAutoFilterBuffer;

sc/source/filter/excel/impop.cxx

     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 );
 
 {
     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 )
 
     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 )
 	{

sc/source/filter/excel/makefile.mk

 		$(SLO)$/excimp8.obj					\
 		$(SLO)$/excrecds.obj				\
 		$(SLO)$/expop2.obj					\
+		$(SLO)$/impop.obj					\
 		$(SLO)$/namebuff.obj				\
 		$(SLO)$/tokstack.obj				\
 		$(SLO)$/xecontent.obj				\

sc/source/filter/excel/read.cxx

     ::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() )
 			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 )
 		{
     ::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
             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();
 

sc/source/filter/excel/xeformula.cxx

 
 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 {

sc/source/filter/excel/xichart.cxx

 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;

sc/source/filter/excel/xilink.cxx

     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 )
     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;
 
 //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.
 };
 {
     sal_uInt16 nXtiCount;
     rStrm >> 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 ) );
 
-    XclImpXti* pXti;
-    while( nXtiCount )
-    {
-        pXti = new XclImpXti;
-        rStrm >> *pXti;
-        maXtiList.Append( pXti );
-        --nXtiCount;
-    }
+    /*  #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();
 }
 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))
         {
     return pSupbook ? pSupbook->GetMacroName( nExtName ) : EMPTY_STRING;
 }
 
-const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt32 nXtiIndex ) const
+const XclImpXti* XclImpLinkManagerImpl::GetXti( sal_uInt16 nXtiIndex ) const
 {
-    const XclImpXti* pXti = maXtiList.GetObject( nXtiIndex );
+    return (nXtiIndex < maXtiList.size()) ? &maXtiList[ nXtiIndex ] : 0;
+}
+
+const XclImpSupbook* XclImpLinkManagerImpl::GetSupbook( sal_uInt16 nXtiIndex ) const
+{
+    const XclImpXti* pXti = GetXti( nXtiIndex );
     return pXti ? maSupbookList.GetObject( pXti->mnSupbook ) : 0;
 }
 

sc/source/filter/excel/xistream.cxx

     return mbValidRec;
 }
 
+bool XclImpStream::StartNextRecord( sal_Size nNextRecPos )
+{
+    mnNextRecPos = nNextRecPos;
+    return StartNextRecord();
+}
+
 void XclImpStream::ResetRecord( bool bContLookup, sal_uInt16 nAltContId )
 {
     if( mbValidRec )

sc/source/filter/excel/xistyle.cxx

     XclImpRoot( rRoot ),
     mpStyleSheet( 0 ),
     mnXclNumFmt( 0 ),
-    mnXclFont( 0 ),
-    mbWasBuiltIn( false ),
-    mbForceCreate( false )
+    mnXclFont( 0 )
 {
 }
 
     }
 }
 
-void XclImpXF::SetStyleName( const String& rStyleName, bool bBuiltIn, bool bForceCreate