LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xelink.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 864 0.0 %
Date: 2014-04-14 Functions: 0 179 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "xelink.hxx"
      21             : 
      22             : #include <algorithm>
      23             : #include <unotools/collatorwrapper.hxx>
      24             : #include <svl/zforlist.hxx>
      25             : #include "document.hxx"
      26             : #include "formulacell.hxx"
      27             : #include "scextopt.hxx"
      28             : #include "externalrefmgr.hxx"
      29             : #include "tokenarray.hxx"
      30             : 
      31             : #include <vector>
      32             : #include <memory>
      33             : 
      34             : using ::std::auto_ptr;
      35             : using ::std::find_if;
      36             : using ::std::vector;
      37             : using ::com::sun::star::uno::Any;
      38             : 
      39             : 
      40             : // *** Helper classes ***
      41             : 
      42             : 
      43             : // External names =============================================================
      44             : 
      45             : /** This is a base class for any external name (i.e. add-in names or DDE links).
      46             :     @descr  Derived classes implement creation and export of the external names. */
      47             : class XclExpExtNameBase : public XclExpRecord, protected XclExpRoot
      48             : {
      49             : public:
      50             :     /** @param nFlags  The flags to export. */
      51             :     explicit            XclExpExtNameBase( const XclExpRoot& rRoot,
      52             :                             const OUString& rName, sal_uInt16 nFlags = 0 );
      53             :     virtual             ~XclExpExtNameBase();
      54             : 
      55             :     /** Returns the name string of the external name. */
      56           0 :     inline const OUString& GetName() const { return maName; }
      57             : 
      58             : private:
      59             :     /** Writes the start of the record that is equal in all EXTERNNAME records and calls WriteAddData(). */
      60             :     virtual void        WriteBody( XclExpStream& rStrm ) SAL_OVERRIDE;
      61             :     /** Called to write additional data following the common record contents.
      62             :         @descr  Derived classes should overwrite this function to write their data. */
      63             :     virtual void        WriteAddData( XclExpStream& rStrm );
      64             : 
      65             : private:
      66             :     OUString            maName;         /// Calc name (title) of the external name.
      67             :     XclExpStringRef     mxName;         /// Excel name (title) of the external name.
      68             :     sal_uInt16          mnFlags;        /// Flags for record export.
      69             : };
      70             : 
      71             : /** Represents an EXTERNNAME record for an add-in function name. */
      72           0 : class XclExpExtNameAddIn : public XclExpExtNameBase
      73             : {
      74             : public:
      75             :     explicit            XclExpExtNameAddIn( const XclExpRoot& rRoot, const OUString& rName );
      76             : 
      77             : private:
      78             :     /** Writes additional record contents. */
      79             :     virtual void        WriteAddData( XclExpStream& rStrm ) SAL_OVERRIDE;
      80             : };
      81             : 
      82             : /** Represents an EXTERNNAME record for a DDE link. */
      83           0 : class XclExpExtNameDde : public XclExpExtNameBase
      84             : {
      85             : public:
      86             :     explicit            XclExpExtNameDde( const XclExpRoot& rRoot, const OUString& rName,
      87             :                             sal_uInt16 nFlags, const ScMatrix* pResults = 0 );
      88             : 
      89             : private:
      90             :     /** Writes additional record contents. */
      91             :     virtual void        WriteAddData( XclExpStream& rStrm ) SAL_OVERRIDE;
      92             : 
      93             : private:
      94             :     typedef boost::shared_ptr< XclExpCachedMatrix > XclExpCachedMatRef;
      95             :     XclExpCachedMatRef  mxMatrix;       /// Cached results of the DDE link.
      96             : };
      97             : 
      98             : class XclExpSupbook;
      99             : 
     100           0 : class XclExpExtName : public XclExpExtNameBase
     101             : {
     102             : public:
     103             :     explicit            XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook, const OUString& rName,
     104             :                                        const ScExternalRefCache::TokenArrayRef pArray );
     105             : 
     106             : private:
     107             :     /** Writes additional record contents. */
     108             :     virtual void        WriteAddData( XclExpStream& rStrm ) SAL_OVERRIDE;
     109             : 
     110             : private:
     111             :     const XclExpSupbook&    mrSupbook;
     112             :     auto_ptr<ScTokenArray>  mpArray;
     113             : };
     114             : 
     115             : // List of external names =====================================================
     116             : 
     117             : /** List of all external names of a sheet. */
     118           0 : class XclExpExtNameBuffer : public XclExpRecordBase, protected XclExpRoot
     119             : {
     120             : public:
     121             :     explicit            XclExpExtNameBuffer( const XclExpRoot& rRoot );
     122             : 
     123             :     /** Inserts an add-in function name
     124             :         @return  The 1-based (Excel-like) list index of the name. */
     125             :     sal_uInt16          InsertAddIn( const OUString& rName );
     126             :     /** InsertEuroTool */
     127             :     sal_uInt16          InsertEuroTool( const OUString& rName );
     128             :     /** Inserts a DDE link.
     129             :         @return  The 1-based (Excel-like) list index of the DDE link. */
     130             :     sal_uInt16          InsertDde( const OUString& rApplic, const OUString& rTopic, const OUString& rItem );
     131             : 
     132             :     sal_uInt16          InsertExtName( const XclExpSupbook& rSupbook, const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray );
     133             : 
     134             :     /** Writes the EXTERNNAME record list. */
     135             :     virtual void        Save( XclExpStream& rStrm ) SAL_OVERRIDE;
     136             : 
     137             : private:
     138             :     typedef XclExpRecordList< XclExpExtNameBase >   XclExpExtNameList;
     139             :     typedef XclExpExtNameList::RecordRefType        XclExpExtNameRef;
     140             : 
     141             : private:
     142             :     /** Returns the 1-based (Excel-like) list index of the external name or 0, if not found. */
     143             :     sal_uInt16          GetIndex( const OUString& rName ) const;
     144             :     /** Appends the passed newly crested external name.
     145             :         @return  The 1-based (Excel-like) list index of the appended name. */
     146             :     sal_uInt16          AppendNew( XclExpExtNameBase* pExtName );
     147             : 
     148             : private:
     149             :     XclExpExtNameList   maNameList;     /// The list with all EXTERNNAME records.
     150             : };
     151             : 
     152             : // Cached external cells ======================================================
     153             : 
     154             : /** Stores the contents of a consecutive row of external cells (record CRN). */
     155           0 : class XclExpCrn : public XclExpRecord
     156             : {
     157             : public:
     158             :     explicit            XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue );
     159             : 
     160             :     /** Returns true, if the passed value could be appended to this record. */
     161             :     bool                InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
     162             : 
     163             : private:
     164             :     virtual void        WriteBody( XclExpStream& rStrm ) SAL_OVERRIDE;
     165             : 
     166             :     void                WriteBool( XclExpStream& rStrm, bool bValue );
     167             :     void                WriteDouble( XclExpStream& rStrm, double fValue );
     168             :     void                WriteString( XclExpStream& rStrm, const OUString& rValue );
     169             :     void                WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode );
     170             :     void                WriteEmpty( XclExpStream& rStrm );
     171             : 
     172             : private:
     173             :     typedef ::std::vector< Any > CachedValues;
     174             : 
     175             :     CachedValues        maValues;   /// All cached values.
     176             :     SCCOL               mnScCol;    /// Column index of the first external cell.
     177             :     SCROW               mnScRow;    /// Row index of the external cells.
     178             : };
     179             : 
     180             : /** Represents the record XCT which is the header record of a CRN record list.
     181             :  */
     182           0 : class XclExpXct : public XclExpRecordBase, protected XclExpRoot
     183             : {
     184             : public:
     185             :     explicit            XclExpXct( const XclExpRoot& rRoot,
     186             :                             const OUString& rTabName, sal_uInt16 nSBTab,
     187             :                             ScExternalRefCache::TableTypeRef xCacheTable );
     188             : 
     189             :     /** Returns the external sheet name. */
     190           0 :     inline const XclExpString& GetTabName() const { return maTabName; }
     191             : 
     192             :     /** Stores all cells in the given range in the CRN list. */
     193             :     void                StoreCellRange( const ScRange& rRange );
     194             : 
     195             :     void                StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken );
     196             :     void                StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken );
     197             : 
     198             :     /** Writes the XCT and all CRN records. */
     199             :     virtual void        Save( XclExpStream& rStrm ) SAL_OVERRIDE;
     200             : 
     201             : private:
     202             :     ScExternalRefCache::TableTypeRef mxCacheTable;
     203             :     ScMarkData          maUsedCells;    /// Contains addresses of all stored cells.
     204             :     ScRange             maBoundRange;   /// Bounding box of maUsedCells.
     205             :     XclExpString        maTabName;      /// Sheet name of the external sheet.
     206             :     sal_uInt16          mnSBTab;        /// Referred sheet index in SUPBOOK record.
     207             : };
     208             : 
     209             : // External documents (EXTERNSHEET/SUPBOOK), base class =======================
     210             : 
     211             : /** Base class for records representing external sheets/documents.
     212             : 
     213             :     In BIFF5/BIFF7, this record is the EXTERNSHEET record containing one sheet
     214             :     of the own or an external document. In BIFF8, this record is the SUPBOOK
     215             :     record representing the entire own or external document with all referenced
     216             :     sheets.
     217             :  */
     218           0 : class XclExpExternSheetBase : public XclExpRecord, protected XclExpRoot
     219             : {
     220             : public:
     221             :     explicit            XclExpExternSheetBase( const XclExpRoot& rRoot,
     222             :                             sal_uInt16 nRecId, sal_uInt32 nRecSize = 0 );
     223             : 
     224             : protected:
     225             :     /** Creates and returns the list of EXTERNNAME records. */
     226             :     XclExpExtNameBuffer& GetExtNameBuffer();
     227             :     /** Creates and returns the list of EXTERNNAME records. */
     228             :     void                WriteExtNameBuffer( XclExpStream& rStrm );
     229             : 
     230             : private:
     231             :     typedef boost::shared_ptr< XclExpExtNameBuffer >   XclExpExtNameBfrRef;
     232             :     XclExpExtNameBfrRef mxExtNameBfr;   /// List of EXTERNNAME records.
     233             : };
     234             : 
     235             : // External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
     236             : 
     237             : /** Represents an EXTERNSHEET record containing the URL and sheet name of a sheet.
     238             :     @descr  This class is used up to BIFF7 only, writing a BIFF8 EXTERNSHEET
     239             :         record is implemented directly in the link manager. */
     240           0 : class XclExpExternSheet : public XclExpExternSheetBase
     241             : {
     242             : public:
     243             :     /** Creates an EXTERNSHEET record containing a special code (i.e. own document or sheet). */
     244             :     explicit            XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode );
     245             :     /** Creates an EXTERNSHEET record referring to an internal sheet. */
     246             :     explicit            XclExpExternSheet( const XclExpRoot& rRoot, const OUString& rTabName );
     247             : 
     248             :     /** Finds or inserts an EXTERNNAME record for add-ins.
     249             :         @return  The 1-based EXTERNNAME record index; or 0, if the record list is full. */
     250             :     sal_uInt16          InsertAddIn( const OUString& rName );
     251             : 
     252             :     /** Writes the EXTERNSHEET and all EXTERNNAME, XCT and CRN records. */
     253             :     virtual void        Save( XclExpStream& rStrm ) SAL_OVERRIDE;
     254             : 
     255             : private:
     256             :     /** Initializes the record data with the passed encoded URL. */
     257             :     void                Init( const OUString& rEncUrl );
     258             :     /** Writes the contents of the EXTERNSHEET  record. */
     259             :     virtual void        WriteBody( XclExpStream& rStrm ) SAL_OVERRIDE;
     260             : 
     261             : private:
     262             :     XclExpString        maTabName;      /// The name of the sheet.
     263             : };
     264             : 
     265             : // External documents (SUPBOOK, BIFF8) ========================================
     266             : 
     267             : /** The SUPBOOK record contains data for an external document (URL, sheet names, external values). */
     268           0 : class XclExpSupbook : public XclExpExternSheetBase
     269             : {
     270             : public:
     271             :     /** Creates a SUPBOOK record for internal references. */
     272             :     explicit            XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount );
     273             :     /** Creates a SUPBOOK record for add-in functions. */
     274             :     explicit            XclExpSupbook( const XclExpRoot& rRoot );
     275             :     /** EUROTOOL SUPBOOK */
     276             :     explicit            XclExpSupbook( const XclExpRoot& rRoot, const OUString& rUrl, XclSupbookType );
     277             :     /** Creates a SUPBOOK record for an external document. */
     278             :     explicit            XclExpSupbook( const XclExpRoot& rRoot, const OUString& rUrl );
     279             :     /** Creates a SUPBOOK record for a DDE link. */
     280             :     explicit            XclExpSupbook( const XclExpRoot& rRoot, const OUString& rApplic, const OUString& rTopic );
     281             : 
     282             :     /** Returns true, if this SUPBOOK contains the passed URL of an external document. */
     283             :     bool                IsUrlLink( const OUString& rUrl ) const;
     284             :     /** Returns true, if this SUPBOOK contains the passed DDE link. */
     285             :     bool                IsDdeLink( const OUString& rApplic, const OUString& rTopic ) const;
     286             :     /** Fills the passed reference log entry with the URL and sheet names. */
     287             :     void                FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
     288             :                             sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const;
     289             : 
     290             :     /** Stores all cells in the given range in the CRN list of the specified SUPBOOK sheet. */
     291             :     void                StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab );
     292             : 
     293             :     void                StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const ::formula::FormulaToken& rToken );
     294             :     void                StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const ::formula::FormulaToken& rToken );
     295             : 
     296             :     sal_uInt16          GetTabIndex( const OUString& rTabName ) const;
     297             :     sal_uInt16          GetTabCount() const;
     298             : 
     299             :     /** Inserts a new sheet name into the SUPBOOK and returns the SUPBOOK internal sheet index. */
     300             :     sal_uInt16          InsertTabName( const OUString& rTabName, ScExternalRefCache::TableTypeRef xCacheTable );
     301             :     /** Finds or inserts an EXTERNNAME record for add-ins.
     302             :         @return  The 1-based EXTERNNAME record index; or 0, if the record list is full. */
     303             :     sal_uInt16          InsertAddIn( const OUString& rName );
     304             :     /** InsertEuroTool */
     305             :     sal_uInt16          InsertEuroTool( const OUString& rName );
     306             :     /** Finds or inserts an EXTERNNAME record for DDE links.
     307             :         @return  The 1-based EXTERNNAME record index; or 0, if the record list is full. */
     308             :     sal_uInt16          InsertDde( const OUString& rItem );
     309             : 
     310             :     sal_uInt16          InsertExtName( const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray );
     311             : 
     312             :     /** Writes the SUPBOOK and all EXTERNNAME, XCT and CRN records. */
     313             :     virtual void        Save( XclExpStream& rStrm ) SAL_OVERRIDE;
     314             : 
     315             : private:
     316             :     /** Returns the sheet name inside of this SUPBOOK. */
     317             :     const XclExpString* GetTabName( sal_uInt16 nSBTab ) const;
     318             : 
     319             :     /** Writes the SUPBOOK record contents. */
     320             :     virtual void        WriteBody( XclExpStream& rStrm ) SAL_OVERRIDE;
     321             : 
     322             : private:
     323             :     typedef XclExpRecordList< XclExpXct >   XclExpXctList;
     324             :     typedef XclExpXctList::RecordRefType    XclExpXctRef;
     325             : 
     326             :     XclExpXctList       maXctList;      /// List of XCT records (which contain CRN records).
     327             :     OUString            maUrl;          /// URL of the external document or application name for DDE.
     328             :     OUString            maDdeTopic;     /// Topic of an DDE link.
     329             :     XclExpString        maUrlEncoded;   /// Document name encoded for Excel.
     330             :     XclSupbookType      meType;         /// Type of this SUPBOOK record.
     331             :     sal_uInt16          mnXclTabCount;  /// Number of internal sheets.
     332             : };
     333             : 
     334             : // All SUPBOOKS in a document =================================================
     335             : 
     336             : /** This struct contains a sheet index range for 3D references.
     337             :     @descr  This reference consists of an index to a SUPBOOK record and indexes
     338             :     to SUPBOOK sheet names. */
     339             : struct XclExpXti
     340             : {
     341             :     sal_uInt16          mnSupbook;      /// Index to SUPBOOK record.
     342             :     sal_uInt16          mnFirstSBTab;   /// Index to the first sheet of the range in the SUPBOOK.
     343             :     sal_uInt16          mnLastSBTab;    /// Index to the last sheet of the range in the SUPBOOK.
     344             : 
     345           0 :     inline explicit     XclExpXti() : mnSupbook( 0 ), mnFirstSBTab( 0 ), mnLastSBTab( 0 ) {}
     346           0 :     inline explicit     XclExpXti( sal_uInt16 nSupbook, sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) :
     347           0 :                             mnSupbook( nSupbook ), mnFirstSBTab( nFirstSBTab ), mnLastSBTab( nLastSBTab ) {}
     348             : 
     349             :     /** Writes this XTI structure (inside of the EXTERNSHEET record). */
     350           0 :     inline void         Save( XclExpStream& rStrm ) const
     351           0 :                             { rStrm << mnSupbook << mnFirstSBTab << mnLastSBTab; }
     352             : };
     353             : 
     354           0 : inline bool operator==( const XclExpXti& rLeft, const XclExpXti& rRight )
     355             : {
     356             :     return
     357           0 :         (rLeft.mnSupbook    == rRight.mnSupbook)    &&
     358           0 :         (rLeft.mnFirstSBTab == rRight.mnFirstSBTab) &&
     359           0 :         (rLeft.mnLastSBTab  == rRight.mnLastSBTab);
     360             : }
     361             : 
     362             : /** Contains a list of all SUPBOOK records and index arrays of external sheets. */
     363           0 : class XclExpSupbookBuffer : public XclExpRecordBase, protected XclExpRoot
     364             : {
     365             : public:
     366             :     explicit            XclExpSupbookBuffer( const XclExpRoot& rRoot );
     367             : 
     368             :     /** Finds SUPBOOK index and SUPBOOK sheet range from given Excel sheet range.
     369             :         @return  An XTI structure containing SUPBOOK and sheet indexes. */
     370             :     XclExpXti           GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
     371             :                             XclExpRefLogEntry* pRefLogEntry = 0 ) const;
     372             : 
     373             :     /** Stores all cells in the given range in a CRN record list. */
     374             :     void                StoreCellRange( const ScRange& rRange );
     375             : 
     376             :     void                StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell );
     377             :     void                StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange );
     378             : 
     379             :     /** Finds or inserts an EXTERNNAME record for an add-in function name.
     380             :         @param rnSupbook  Returns the index of the SUPBOOK record which contains the add-in function name.
     381             :         @param rnExtName  Returns the 1-based EXTERNNAME record index. */
     382             :     bool                InsertAddIn(
     383             :                             sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
     384             :                             const OUString& rName );
     385             :     /** InsertEuroTool */
     386             :     bool                InsertEuroTool(
     387             :                              sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
     388             :                              const OUString& rName );
     389             :     /** Finds or inserts an EXTERNNAME record for DDE links.
     390             :         @param rnSupbook  Returns the index of the SUPBOOK record which contains the DDE link.
     391             :         @param rnExtName  Returns the 1-based EXTERNNAME record index. */
     392             :     bool                InsertDde(
     393             :                             sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
     394             :                             const OUString& rApplic, const OUString& rTopic, const OUString& rItem );
     395             : 
     396             :     bool                InsertExtName(
     397             :                             sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const OUString& rUrl,
     398             :                             const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray );
     399             : 
     400             :     XclExpXti           GetXti( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
     401             :                                 XclExpRefLogEntry* pRefLogEntry = NULL );
     402             : 
     403             :     /** Writes all SUPBOOK records with their sub records. */
     404             :     virtual void        Save( XclExpStream& rStrm ) SAL_OVERRIDE;
     405             : 
     406             :     struct XclExpSBIndex
     407             :     {
     408             :         sal_uInt16          mnSupbook;          /// SUPBOOK index for an Excel sheet.
     409             :         sal_uInt16          mnSBTab;            /// Sheet name index in SUPBOOK for an Excel sheet.
     410           0 :         inline void         Set( sal_uInt16 nSupbook, sal_uInt16 nSBTab )
     411           0 :                                 { mnSupbook = nSupbook; mnSBTab = nSBTab; }
     412             :     };
     413             :     typedef ::std::vector< XclExpSBIndex > XclExpSBIndexVec;
     414             : 
     415             : private:
     416             :     typedef XclExpRecordList< XclExpSupbook >   XclExpSupbookList;
     417             :     typedef XclExpSupbookList::RecordRefType    XclExpSupbookRef;
     418             : 
     419             : private:
     420             :     /** Searches for the SUPBOOK record containing the passed document URL.
     421             :         @param rxSupbook  (out-param) Returns a reference to the SUPBOOK record, or 0.
     422             :         @param rnIndex  (out-param) Returns the list index, if the SUPBOOK exists.
     423             :         @return  True, if the SUPBOOK record exists (out-parameters are valid). */
     424             :     bool                GetSupbookUrl( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
     425             :                             const OUString& rUrl ) const;
     426             :     /** Searches for the SUPBOOK record containing the passed DDE link.
     427             :         @param rxSupbook  (out-param) Returns a reference to the SUPBOOK record, or 0.
     428             :         @param rnIndex  (out-param) Returns the list index, if the SUPBOOK exists.
     429             :         @return  True, if the SUPBOOK record exists (out-parameters are valid). */
     430             :     bool                GetSupbookDde( XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex,
     431             :                             const OUString& rApplic, const OUString& rTopic ) const;
     432             : 
     433             :     /** Appends a new SUPBOOK to the list.
     434             :         @return  The list index of the SUPBOOK record. */
     435             :     sal_uInt16          Append( XclExpSupbookRef xSupbook );
     436             : 
     437             : private:
     438             :     XclExpSupbookList   maSupbookList;      /// List of all SUPBOOK records.
     439             :     XclExpSBIndexVec    maSBIndexVec;       /// SUPBOOK and sheet name index for each Excel sheet.
     440             :     sal_uInt16          mnOwnDocSB;         /// Index to SUPBOOK for own document.
     441             :     sal_uInt16          mnAddInSB;          /// Index to add-in SUPBOOK.
     442             : };
     443             : 
     444             : // Export link manager ========================================================
     445             : 
     446             : /** Abstract base class for implementation classes of the link manager. */
     447           0 : class XclExpLinkManagerImpl : protected XclExpRoot
     448             : {
     449             : public:
     450             :     /** Derived classes search for an EXTSHEET structure for the given Calc sheet range. */
     451             :     virtual void        FindExtSheet( sal_uInt16& rnExtSheet,
     452             :                             sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
     453             :                             SCTAB nFirstScTab, SCTAB nLastScTab,
     454             :                             XclExpRefLogEntry* pRefLogEntry ) = 0;
     455             :     /** Derived classes search for a special EXTERNSHEET index for the own document. */
     456             :     virtual sal_uInt16  FindExtSheet( sal_Unicode cCode ) = 0;
     457             : 
     458             :     virtual void FindExtSheet( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
     459             :                                sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
     460             :                                XclExpRefLogEntry* pRefLogEntry ) = 0;
     461             : 
     462             :     /** Derived classes store all cells in the given range in a CRN record list. */
     463             :     virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2, const ScAddress& rPos ) = 0;
     464             : 
     465             :     virtual void StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos ) = 0;
     466             :     virtual void StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange ) = 0;
     467             : 
     468             :     /** Derived classes find or insert an EXTERNNAME record for an add-in function name. */
     469             :     virtual bool        InsertAddIn(
     470             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
     471             :                             const OUString& rName ) = 0;
     472             :     /** InsertEuroTool */
     473             :     virtual bool        InsertEuroTool(
     474             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
     475             :                             const OUString& rName ) = 0;
     476             : 
     477             :     /** Derived classes find or insert an EXTERNNAME record for DDE links. */
     478             :     virtual bool        InsertDde(
     479             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
     480             :                             const OUString& rApplic, const OUString& rTopic, const OUString& rItem ) = 0;
     481             : 
     482             :     virtual bool        InsertExtName(
     483             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rUrl,
     484             :                             const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray ) = 0;
     485             : 
     486             :     /** Derived classes write the entire link table to the passed stream. */
     487             :     virtual void        Save( XclExpStream& rStrm ) = 0;
     488             : 
     489             : protected:
     490             :     explicit            XclExpLinkManagerImpl( const XclExpRoot& rRoot );
     491             : };
     492             : 
     493             : /** Implementation of the link manager for BIFF5/BIFF7. */
     494           0 : class XclExpLinkManagerImpl5 : public XclExpLinkManagerImpl
     495             : {
     496             : public:
     497             :     explicit            XclExpLinkManagerImpl5( const XclExpRoot& rRoot );
     498             : 
     499             :     virtual void        FindExtSheet( sal_uInt16& rnExtSheet,
     500             :                             sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
     501             :                             SCTAB nFirstScTab, SCTAB nLastScTab,
     502             :                             XclExpRefLogEntry* pRefLogEntry ) SAL_OVERRIDE;
     503             :     virtual sal_uInt16  FindExtSheet( sal_Unicode cCode ) SAL_OVERRIDE;
     504             : 
     505             :     virtual void FindExtSheet( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
     506             :                                sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
     507             :                                XclExpRefLogEntry* pRefLogEntry ) SAL_OVERRIDE;
     508             : 
     509             :     virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2, const ScAddress& rPos ) SAL_OVERRIDE;
     510             : 
     511             :     virtual void StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos ) SAL_OVERRIDE;
     512             :     virtual void StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange ) SAL_OVERRIDE;
     513             : 
     514             :     virtual bool        InsertAddIn(
     515             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
     516             :                             const OUString& rName ) SAL_OVERRIDE;
     517             : 
     518             :     /** InsertEuroTool */
     519             :     virtual bool        InsertEuroTool(
     520             :                              sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
     521             :                              const OUString& rName ) SAL_OVERRIDE;
     522             : 
     523             :     virtual bool        InsertDde(
     524             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
     525             :                             const OUString& rApplic, const OUString& rTopic, const OUString& rItem ) SAL_OVERRIDE;
     526             : 
     527             :     virtual bool        InsertExtName(
     528             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rUrl,
     529             :                             const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray ) SAL_OVERRIDE;
     530             : 
     531             :     virtual void        Save( XclExpStream& rStrm ) SAL_OVERRIDE;
     532             : 
     533             : private:
     534             :     typedef XclExpRecordList< XclExpExternSheet >   XclExpExtSheetList;
     535             :     typedef XclExpExtSheetList::RecordRefType       XclExpExtSheetRef;
     536             :     typedef ::std::map< SCTAB, sal_uInt16 >         XclExpIntTabMap;
     537             :     typedef ::std::map< sal_Unicode, sal_uInt16 >   XclExpCodeMap;
     538             : 
     539             : private:
     540             :     /** Returns the number of EXTERNSHEET records. */
     541             :     sal_uInt16          GetExtSheetCount() const;
     542             : 
     543             :     /** Appends an internal EXTERNSHEET record and returns the one-based index. */
     544             :     sal_uInt16          AppendInternal( XclExpExtSheetRef xExtSheet );
     545             :     /** Creates all EXTERNSHEET records for internal sheets on first call. */
     546             :     void                CreateInternal();
     547             : 
     548             :     /** Returns the specified internal EXTERNSHEET record. */
     549             :     XclExpExtSheetRef   GetInternal( sal_uInt16 nExtSheet );
     550             :     /** Returns the EXTERNSHEET index of an internal Calc sheet, or a deleted reference. */
     551             :     XclExpExtSheetRef   FindInternal( sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab );
     552             :     /** Finds or creates the EXTERNSHEET index of an internal special EXTERNSHEET. */
     553             :     XclExpExtSheetRef   FindInternal( sal_uInt16& rnExtSheet, sal_Unicode cCode );
     554             : 
     555             : private:
     556             :     XclExpExtSheetList  maExtSheetList;     /// List with EXTERNSHEET records.
     557             :     XclExpIntTabMap     maIntTabMap;        /// Maps internal Calc sheets to EXTERNSHEET records.
     558             :     XclExpCodeMap       maCodeMap;          /// Maps special external codes to EXTERNSHEET records.
     559             : };
     560             : 
     561             : /** Implementation of the link manager for BIFF8. */
     562           0 : class XclExpLinkManagerImpl8 : public XclExpLinkManagerImpl
     563             : {
     564             : public:
     565             :     explicit            XclExpLinkManagerImpl8( const XclExpRoot& rRoot );
     566             : 
     567             :     virtual void        FindExtSheet( sal_uInt16& rnExtSheet,
     568             :                             sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
     569             :                             SCTAB nFirstScTab, SCTAB nLastScTab,
     570             :                             XclExpRefLogEntry* pRefLogEntry ) SAL_OVERRIDE;
     571             :     virtual sal_uInt16  FindExtSheet( sal_Unicode cCode ) SAL_OVERRIDE;
     572             : 
     573             :     virtual void FindExtSheet( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
     574             :                                sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
     575             :                                XclExpRefLogEntry* pRefLogEntry ) SAL_OVERRIDE;
     576             : 
     577             :     virtual void StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2, const ScAddress& rPos ) SAL_OVERRIDE;
     578             : 
     579             :     virtual void StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos ) SAL_OVERRIDE;
     580             :     virtual void StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange ) SAL_OVERRIDE;
     581             : 
     582             :     virtual bool        InsertAddIn(
     583             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
     584             :                             const OUString& rName ) SAL_OVERRIDE;
     585             :     /** InsertEuroTool */
     586             :     virtual bool        InsertEuroTool(
     587             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
     588             :                             const OUString& rName ) SAL_OVERRIDE;
     589             : 
     590             :     virtual bool        InsertDde(
     591             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
     592             :                             const OUString& rApplic, const OUString& rTopic, const OUString& rItem ) SAL_OVERRIDE;
     593             : 
     594             :     virtual bool        InsertExtName(
     595             :                             sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rUrl,
     596             :                             const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray ) SAL_OVERRIDE;
     597             : 
     598             :     virtual void        Save( XclExpStream& rStrm ) SAL_OVERRIDE;
     599             : 
     600             : private:
     601             :     /** Searches for or inserts a new XTI structure.
     602             :         @return  The 0-based list index of the XTI structure. */
     603             :     sal_uInt16          InsertXti( const XclExpXti& rXti );
     604             : 
     605             : private:
     606             :     typedef ::std::vector< XclExpXti > XclExpXtiVec;
     607             : 
     608             :     XclExpSupbookBuffer maSBBuffer;     /// List of all SUPBOOK records.
     609             :     XclExpXtiVec        maXtiVec;       /// List of XTI structures for the EXTERNSHEET record.
     610             : };
     611             : 
     612             : 
     613             : // *** Implementation ***
     614             : 
     615             : 
     616             : // Excel sheet indexes ========================================================
     617             : 
     618             : const sal_uInt8 EXC_TABBUF_IGNORE   = 0x01;     /// Sheet will be ignored completely.
     619             : const sal_uInt8 EXC_TABBUF_EXTERN   = 0x02;     /// Sheet is linked externally.
     620             : const sal_uInt8 EXC_TABBUF_SKIPMASK = 0x0F;     /// Sheet will be skipped, if any flag is set.
     621             : const sal_uInt8 EXC_TABBUF_VISIBLE  = 0x10;     /// Sheet is visible.
     622             : const sal_uInt8 EXC_TABBUF_SELECTED = 0x20;     /// Sheet is selected.
     623             : const sal_uInt8 EXC_TABBUF_MIRRORED = 0x40;     /// Sheet is mirrored (right-to-left).
     624             : 
     625           0 : XclExpTabInfo::XclExpTabInfo( const XclExpRoot& rRoot ) :
     626             :     XclExpRoot( rRoot ),
     627             :     mnScCnt( 0 ),
     628             :     mnXclCnt( 0 ),
     629             :     mnXclExtCnt( 0 ),
     630             :     mnXclSelCnt( 0 ),
     631             :     mnDisplXclTab( 0 ),
     632           0 :     mnFirstVisXclTab( 0 )
     633             : {
     634           0 :     ScDocument& rDoc = GetDoc();
     635           0 :     ScExtDocOptions& rDocOpt = GetExtDocOptions();
     636             : 
     637           0 :     mnScCnt = rDoc.GetTableCount();
     638             : 
     639             :     SCTAB nScTab;
     640           0 :     SCTAB nFirstVisScTab = SCTAB_INVALID;   // first visible sheet
     641           0 :     SCTAB nFirstExpScTab = SCTAB_INVALID;   // first exported sheet
     642             : 
     643             :     // --- initialize the flags in the index buffer ---
     644             : 
     645           0 :     maTabInfoVec.resize( mnScCnt );
     646           0 :     for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
     647             :     {
     648             :         // ignored sheets (skipped by export, with invalid Excel sheet index)
     649           0 :         if( rDoc.IsScenario( nScTab ) )
     650             :         {
     651           0 :             SetFlag( nScTab, EXC_TABBUF_IGNORE );
     652             :         }
     653             : 
     654             :         // external sheets (skipped, but with valid Excel sheet index for ref's)
     655           0 :         else if( rDoc.GetLinkMode( nScTab ) == SC_LINK_VALUE )
     656             :         {
     657           0 :             SetFlag( nScTab, EXC_TABBUF_EXTERN );
     658             :         }
     659             : 
     660             :         // exported sheets
     661             :         else
     662             :         {
     663             :             // sheet name
     664           0 :             rDoc.GetName( nScTab, maTabInfoVec[ nScTab ].maScName );
     665             : 
     666             :             // remember first exported sheet
     667           0 :             if( nFirstExpScTab == SCTAB_INVALID )
     668           0 :                nFirstExpScTab = nScTab;
     669             :             // remember first visible exported sheet
     670           0 :             if( (nFirstVisScTab == SCTAB_INVALID) && rDoc.IsVisible( nScTab ) )
     671           0 :                nFirstVisScTab = nScTab;
     672             : 
     673             :             // sheet visible (only exported sheets)
     674           0 :             SetFlag( nScTab, EXC_TABBUF_VISIBLE, rDoc.IsVisible( nScTab ) );
     675             : 
     676             :             // sheet selected (only exported sheets)
     677           0 :             if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nScTab ) )
     678           0 :                 SetFlag( nScTab, EXC_TABBUF_SELECTED, pTabSett->mbSelected );
     679             : 
     680             :             // sheet mirrored (only exported sheets)
     681           0 :             SetFlag( nScTab, EXC_TABBUF_MIRRORED, rDoc.IsLayoutRTL( nScTab ) );
     682             :         }
     683             :     }
     684             : 
     685             :     // --- visible/selected sheets ---
     686             : 
     687           0 :     SCTAB nDisplScTab = rDocOpt.GetDocSettings().mnDisplTab;
     688             : 
     689             :     // find first visible exported sheet
     690           0 :     if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
     691             :     {
     692             :         // no exportable visible sheet -> use first exportable sheet
     693           0 :         nFirstVisScTab = nFirstExpScTab;
     694           0 :         if( (nFirstVisScTab == SCTAB_INVALID) || !IsExportTab( nFirstVisScTab ) )
     695             :         {
     696             :             // no exportable sheet at all -> use active sheet and export it
     697           0 :             nFirstVisScTab = nDisplScTab;
     698           0 :             SetFlag( nFirstVisScTab, EXC_TABBUF_SKIPMASK, false ); // clear skip flags
     699             :         }
     700           0 :         SetFlag( nFirstVisScTab, EXC_TABBUF_VISIBLE ); // must be visible, even if originally hidden
     701             :     }
     702             : 
     703             :     // find currently displayed sheet
     704           0 :     if( !IsExportTab( nDisplScTab ) )   // selected sheet not exported (i.e. scenario) -> use first visible
     705           0 :         nDisplScTab = nFirstVisScTab;
     706           0 :     SetFlag( nDisplScTab, EXC_TABBUF_VISIBLE | EXC_TABBUF_SELECTED );
     707             : 
     708             :     // number of selected sheets
     709           0 :     for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
     710           0 :         if( IsSelectedTab( nScTab ) )
     711           0 :             ++mnXclSelCnt;
     712             : 
     713             :     // --- calculate resulting Excel sheet indexes ---
     714             : 
     715           0 :     CalcXclIndexes();
     716           0 :     mnFirstVisXclTab = GetXclTab( nFirstVisScTab );
     717           0 :     mnDisplXclTab = GetXclTab( nDisplScTab );
     718             : 
     719             :     // --- sorted vectors for index lookup ---
     720             : 
     721           0 :     CalcSortedIndexes();
     722           0 : }
     723             : 
     724           0 : bool XclExpTabInfo::IsExportTab( SCTAB nScTab ) const
     725             : {
     726             :     /*  Check sheet index before to avoid assertion in GetFlag(). */
     727           0 :     return (nScTab < mnScCnt) && !GetFlag( nScTab, EXC_TABBUF_SKIPMASK );
     728             : }
     729             : 
     730           0 : bool XclExpTabInfo::IsExternalTab( SCTAB nScTab ) const
     731             : {
     732             :     /*  Check sheet index before to avoid assertion (called from formula
     733             :         compiler also for deleted references). */
     734           0 :     return (nScTab < mnScCnt) && GetFlag( nScTab, EXC_TABBUF_EXTERN );
     735             : }
     736             : 
     737           0 : bool XclExpTabInfo::IsVisibleTab( SCTAB nScTab ) const
     738             : {
     739           0 :     return GetFlag( nScTab, EXC_TABBUF_VISIBLE );
     740             : }
     741             : 
     742           0 : bool XclExpTabInfo::IsSelectedTab( SCTAB nScTab ) const
     743             : {
     744           0 :     return GetFlag( nScTab, EXC_TABBUF_SELECTED );
     745             : }
     746             : 
     747           0 : bool XclExpTabInfo::IsDisplayedTab( SCTAB nScTab ) const
     748             : {
     749             :     OSL_ENSURE( nScTab < mnScCnt, "XclExpTabInfo::IsActiveTab - sheet out of range" );
     750           0 :     return GetXclTab( nScTab ) == mnDisplXclTab;
     751             : }
     752             : 
     753           0 : bool XclExpTabInfo::IsMirroredTab( SCTAB nScTab ) const
     754             : {
     755           0 :     return GetFlag( nScTab, EXC_TABBUF_MIRRORED );
     756             : }
     757             : 
     758           0 : OUString XclExpTabInfo::GetScTabName( SCTAB nScTab ) const
     759             : {
     760             :     OSL_ENSURE( nScTab < mnScCnt, "XclExpTabInfo::IsActiveTab - sheet out of range" );
     761           0 :     return (nScTab < mnScCnt) ? maTabInfoVec[ nScTab ].maScName : OUString();
     762             : }
     763             : 
     764           0 : sal_uInt16 XclExpTabInfo::GetXclTab( SCTAB nScTab ) const
     765             : {
     766           0 :     return (nScTab < mnScCnt) ? maTabInfoVec[ nScTab ].mnXclTab : EXC_TAB_DELETED;
     767             : }
     768             : 
     769           0 : SCTAB XclExpTabInfo::GetRealScTab( SCTAB nSortedScTab ) const
     770             : {
     771             :     OSL_ENSURE( nSortedScTab < mnScCnt, "XclExpTabInfo::GetRealScTab - sheet out of range" );
     772           0 :     return (nSortedScTab < mnScCnt) ? maFromSortedVec[ nSortedScTab ] : SCTAB_INVALID;
     773             : }
     774             : 
     775           0 : bool XclExpTabInfo::GetFlag( SCTAB nScTab, sal_uInt8 nFlags ) const
     776             : {
     777             :     OSL_ENSURE( nScTab < mnScCnt, "XclExpTabInfo::GetFlag - sheet out of range" );
     778           0 :     return (nScTab < mnScCnt) && ::get_flag( maTabInfoVec[ nScTab ].mnFlags, nFlags );
     779             : }
     780             : 
     781           0 : void XclExpTabInfo::SetFlag( SCTAB nScTab, sal_uInt8 nFlags, bool bSet )
     782             : {
     783             :     OSL_ENSURE( nScTab < mnScCnt, "XclExpTabInfo::SetFlag - sheet out of range" );
     784           0 :     if( nScTab < mnScCnt )
     785           0 :         ::set_flag( maTabInfoVec[ nScTab ].mnFlags, nFlags, bSet );
     786           0 : }
     787             : 
     788           0 : void XclExpTabInfo::CalcXclIndexes()
     789             : {
     790           0 :     sal_uInt16 nXclTab = 0;
     791           0 :     SCTAB nScTab = 0;
     792             : 
     793             :     // --- pass 1: process regular sheets ---
     794           0 :     for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
     795             :     {
     796           0 :         if( IsExportTab( nScTab ) )
     797             :         {
     798           0 :             maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
     799           0 :             ++nXclTab;
     800             :         }
     801             :         else
     802           0 :             maTabInfoVec[ nScTab ].mnXclTab = EXC_TAB_DELETED;
     803             :     }
     804           0 :     mnXclCnt = nXclTab;
     805             : 
     806             :     // --- pass 2: process external sheets (nXclTab continues) ---
     807           0 :     for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
     808             :     {
     809           0 :         if( IsExternalTab( nScTab ) )
     810             :         {
     811           0 :             maTabInfoVec[ nScTab ].mnXclTab = nXclTab;
     812           0 :             ++nXclTab;
     813           0 :             ++mnXclExtCnt;
     814             :         }
     815             :     }
     816             : 
     817             :     // result: first occur all exported sheets, followed by all external sheets
     818           0 : }
     819             : 
     820             : typedef ::std::pair< OUString, SCTAB > XclExpTabName;
     821             : typedef ::std::vector< XclExpTabName >  XclExpTabNameVec;
     822             : 
     823             : inline bool operator<( const XclExpTabName& rArg1, const XclExpTabName& rArg2 )
     824             : {
     825             :     // compare the sheet names only
     826             :     return ScGlobal::GetCollator()->compareString( rArg1.first, rArg2.first ) < 0;
     827             : }
     828             : 
     829           0 : void XclExpTabInfo::CalcSortedIndexes()
     830             : {
     831           0 :     ScDocument& rDoc = GetDoc();
     832           0 :     XclExpTabNameVec aVec( mnScCnt );
     833             :     SCTAB nScTab;
     834             : 
     835             :     // fill with sheet names
     836           0 :     for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
     837             :     {
     838           0 :         rDoc.GetName( nScTab, aVec[ nScTab ].first );
     839           0 :         aVec[ nScTab ].second = nScTab;
     840             :     }
     841           0 :     ::std::sort( aVec.begin(), aVec.end() );
     842             : 
     843             :     // fill index vectors from sorted sheet name vector
     844           0 :     maFromSortedVec.resize( mnScCnt );
     845           0 :     maToSortedVec.resize( mnScCnt );
     846           0 :     for( nScTab = 0; nScTab < mnScCnt; ++nScTab )
     847             :     {
     848           0 :         maFromSortedVec[ nScTab ] = aVec[ nScTab ].second;
     849           0 :         maToSortedVec[ aVec[ nScTab ].second ] = nScTab;
     850           0 :     }
     851           0 : }
     852             : 
     853             : // External names =============================================================
     854             : 
     855           0 : XclExpExtNameBase::XclExpExtNameBase(
     856             :         const XclExpRoot& rRoot, const OUString& rName, sal_uInt16 nFlags ) :
     857             :     XclExpRecord( EXC_ID_EXTERNNAME ),
     858             :     XclExpRoot( rRoot ),
     859             :     maName( rName ),
     860             :     mxName( XclExpStringHelper::CreateString( rRoot, rName, EXC_STR_8BITLENGTH ) ),
     861           0 :     mnFlags( nFlags )
     862             : {
     863             :     OSL_ENSURE( maName.getLength() <= 255, "XclExpExtNameBase::XclExpExtNameBase - string too long" );
     864           0 :     SetRecSize( 6 + mxName->GetSize() );
     865           0 : }
     866             : 
     867           0 : XclExpExtNameBase::~XclExpExtNameBase()
     868             : {
     869           0 : }
     870             : 
     871           0 : void XclExpExtNameBase::WriteBody( XclExpStream& rStrm )
     872             : {
     873           0 :     rStrm   << mnFlags
     874           0 :             << sal_uInt32( 0 )
     875           0 :             << *mxName;
     876           0 :     WriteAddData( rStrm );
     877           0 : }
     878             : 
     879           0 : void XclExpExtNameBase::WriteAddData( XclExpStream& /*rStrm*/ )
     880             : {
     881           0 : }
     882             : 
     883           0 : XclExpExtNameAddIn::XclExpExtNameAddIn( const XclExpRoot& rRoot, const OUString& rName ) :
     884           0 :     XclExpExtNameBase( rRoot, rName )
     885             : {
     886           0 :     AddRecSize( 4 );
     887           0 : }
     888             : 
     889           0 : void XclExpExtNameAddIn::WriteAddData( XclExpStream& rStrm )
     890             : {
     891             :     // write a #REF! error formula
     892           0 :     rStrm << sal_uInt16( 2 ) << EXC_TOKID_ERR << EXC_ERR_REF;
     893           0 : }
     894             : 
     895           0 : XclExpExtNameDde::XclExpExtNameDde( const XclExpRoot& rRoot,
     896             :         const OUString& rName, sal_uInt16 nFlags, const ScMatrix* pResults ) :
     897           0 :     XclExpExtNameBase( rRoot, rName, nFlags )
     898             : {
     899           0 :     if( pResults )
     900             :     {
     901           0 :         mxMatrix.reset( new XclExpCachedMatrix( *pResults ) );
     902           0 :         AddRecSize( mxMatrix->GetSize() );
     903             :     }
     904           0 : }
     905             : 
     906           0 : void XclExpExtNameDde::WriteAddData( XclExpStream& rStrm )
     907             : {
     908           0 :     if( mxMatrix )
     909           0 :         mxMatrix->Save( rStrm );
     910           0 : }
     911             : 
     912           0 : XclExpExtName::XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook,
     913             :         const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray ) :
     914             :     XclExpExtNameBase( rRoot, rName ),
     915             :     mrSupbook(rSupbook),
     916           0 :     mpArray(pArray->Clone())
     917             : {
     918           0 : }
     919             : 
     920           0 : void XclExpExtName::WriteAddData( XclExpStream& rStrm )
     921             : {
     922             :     // Write only if it only has a single token that is either a cell or cell
     923             :     // range address.  Excel just writes '02 00 1C 17' for all the other types
     924             :     // of external names.
     925             : 
     926             :     using namespace ::formula;
     927             :     do
     928             :     {
     929           0 :         if (mpArray->GetLen() != 1)
     930           0 :             break;
     931             : 
     932           0 :         const ScToken* p = static_cast<const ScToken*>(mpArray->First());
     933           0 :         if (!p->IsExternalRef())
     934           0 :             break;
     935             : 
     936           0 :         switch (p->GetType())
     937             :         {
     938             :             case svExternalSingleRef:
     939             :             {
     940           0 :                 const ScSingleRefData& rRef = p->GetSingleRef();
     941           0 :                 if (rRef.IsTabRel())
     942           0 :                     break;
     943             : 
     944           0 :                 bool bColRel = rRef.IsColRel();
     945           0 :                 bool bRowRel = rRef.IsRowRel();
     946           0 :                 sal_uInt16 nCol = static_cast<sal_uInt16>(rRef.Col());
     947           0 :                 sal_uInt16 nRow = static_cast<sal_uInt16>(rRef.Row());
     948           0 :                 if (bColRel) nCol |= 0x4000;
     949           0 :                 if (bRowRel) nCol |= 0x8000;
     950             : 
     951           0 :                 OUString aTabName = p->GetString().getString();
     952           0 :                 sal_uInt16 nSBTab = mrSupbook.GetTabIndex(aTabName);
     953             : 
     954             :                 // size is always 9
     955           0 :                 rStrm << static_cast<sal_uInt16>(9);
     956             :                 // operator token (3A for cell reference)
     957           0 :                 rStrm << static_cast<sal_uInt8>(0x3A);
     958             :                 // cell address (Excel's address has 2 sheet IDs.)
     959           0 :                 rStrm << nSBTab << nSBTab << nRow << nCol;
     960           0 :                 return;
     961             :             }
     962             :             case svExternalDoubleRef:
     963             :             {
     964           0 :                 const ScComplexRefData& rRef = p->GetDoubleRef();
     965           0 :                 const ScSingleRefData& r1 = rRef.Ref1;
     966           0 :                 const ScSingleRefData& r2 = rRef.Ref2;
     967           0 :                 if (r1.IsTabRel() || r2.IsTabRel())
     968           0 :                     break;
     969             : 
     970           0 :                 sal_uInt16 nTab1 = r1.Tab();
     971           0 :                 sal_uInt16 nTab2 = r2.Tab();
     972           0 :                 bool bCol1Rel = r1.IsColRel();
     973           0 :                 bool bRow1Rel = r1.IsRowRel();
     974           0 :                 bool bCol2Rel = r2.IsColRel();
     975           0 :                 bool bRow2Rel = r2.IsRowRel();
     976             : 
     977           0 :                 sal_uInt16 nCol1 = static_cast<sal_uInt16>(r1.Col());
     978           0 :                 sal_uInt16 nCol2 = static_cast<sal_uInt16>(r2.Col());
     979           0 :                 sal_uInt16 nRow1 = static_cast<sal_uInt16>(r1.Row());
     980           0 :                 sal_uInt16 nRow2 = static_cast<sal_uInt16>(r2.Row());
     981           0 :                 if (bCol1Rel) nCol1 |= 0x4000;
     982           0 :                 if (bRow1Rel) nCol1 |= 0x8000;
     983           0 :                 if (bCol2Rel) nCol2 |= 0x4000;
     984           0 :                 if (bRow2Rel) nCol2 |= 0x8000;
     985             : 
     986           0 :                 OUString aTabName = p->GetString().getString();
     987           0 :                 sal_uInt16 nSBTab = mrSupbook.GetTabIndex(aTabName);
     988             : 
     989             :                 // size is always 13 (0x0D)
     990           0 :                 rStrm << static_cast<sal_uInt16>(13);
     991             :                 // operator token (3B for area reference)
     992           0 :                 rStrm << static_cast<sal_uInt8>(0x3B);
     993             :                 // range (area) address
     994           0 :                 sal_uInt16 nSBTab2 = nSBTab + nTab2 - nTab1;
     995           0 :                 rStrm << nSBTab << nSBTab2 << nRow1 << nRow2 << nCol1 << nCol2;
     996           0 :                 return;
     997             :             }
     998             :             default:
     999             :                 ;   // nothing
    1000             :         }
    1001             :     }
    1002             :     while (false);
    1003             : 
    1004             :     // special value for #REF! (02 00 1C 17)
    1005           0 :     rStrm << static_cast<sal_uInt16>(2) << EXC_TOKID_ERR << EXC_ERR_REF;
    1006             : }
    1007             : 
    1008             : // List of external names =====================================================
    1009             : 
    1010           0 : XclExpExtNameBuffer::XclExpExtNameBuffer( const XclExpRoot& rRoot ) :
    1011           0 :     XclExpRoot( rRoot )
    1012             : {
    1013           0 : }
    1014             : 
    1015           0 : sal_uInt16 XclExpExtNameBuffer::InsertAddIn( const OUString& rName )
    1016             : {
    1017           0 :     sal_uInt16 nIndex = GetIndex( rName );
    1018           0 :     return nIndex ? nIndex : AppendNew( new XclExpExtNameAddIn( GetRoot(), rName ) );
    1019             : }
    1020             : 
    1021           0 : sal_uInt16 XclExpExtNameBuffer::InsertEuroTool( const OUString& rName )
    1022             : {
    1023           0 :     sal_uInt16 nIndex = GetIndex( rName );
    1024           0 :     return nIndex ? nIndex : AppendNew( new XclExpExtNameBase( GetRoot(), rName ) );
    1025             : }
    1026             : 
    1027           0 : sal_uInt16 XclExpExtNameBuffer::InsertDde(
    1028             :         const OUString& rApplic, const OUString& rTopic, const OUString& rItem )
    1029             : {
    1030           0 :     sal_uInt16 nIndex = GetIndex( rItem );
    1031           0 :     if( nIndex == 0 )
    1032             :     {
    1033             :         size_t nPos;
    1034           0 :         if( GetDoc().FindDdeLink( rApplic, rTopic, rItem, SC_DDE_IGNOREMODE, nPos ) )
    1035             :         {
    1036             :             // create the leading 'StdDocumentName' EXTERNNAME record
    1037           0 :             if( maNameList.IsEmpty() )
    1038             :                 AppendNew( new XclExpExtNameDde(
    1039           0 :                     GetRoot(), OUString("StdDocumentName"), EXC_EXTN_EXPDDE_STDDOC ) );
    1040             : 
    1041             :             // try to find DDE result array, but create EXTERNNAME record without them too
    1042           0 :             const ScMatrix* pScMatrix = GetDoc().GetDdeLinkResultMatrix( nPos );
    1043           0 :             nIndex = AppendNew( new XclExpExtNameDde( GetRoot(), rItem, EXC_EXTN_EXPDDE, pScMatrix ) );
    1044             :         }
    1045             :     }
    1046           0 :     return nIndex;
    1047             : }
    1048             : 
    1049           0 : sal_uInt16 XclExpExtNameBuffer::InsertExtName( const XclExpSupbook& rSupbook,
    1050             :         const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray )
    1051             : {
    1052           0 :     sal_uInt16 nIndex = GetIndex( rName );
    1053           0 :     return nIndex ? nIndex : AppendNew( new XclExpExtName( GetRoot(), rSupbook, rName, pArray ) );
    1054             : }
    1055             : 
    1056           0 : void XclExpExtNameBuffer::Save( XclExpStream& rStrm )
    1057             : {
    1058           0 :     maNameList.Save( rStrm );
    1059           0 : }
    1060             : 
    1061           0 : sal_uInt16 XclExpExtNameBuffer::GetIndex( const OUString& rName ) const
    1062             : {
    1063           0 :     for( size_t nPos = 0, nSize = maNameList.GetSize(); nPos < nSize; ++nPos )
    1064           0 :         if( maNameList.GetRecord( nPos )->GetName() == rName )
    1065           0 :             return static_cast< sal_uInt16 >( nPos + 1 );
    1066           0 :     return 0;
    1067             : }
    1068             : 
    1069           0 : sal_uInt16 XclExpExtNameBuffer::AppendNew( XclExpExtNameBase* pExtName )
    1070             : {
    1071           0 :     XclExpExtNameRef xExtName( pExtName );
    1072           0 :     size_t nSize = maNameList.GetSize();
    1073           0 :     if( nSize < 0x7FFF )
    1074             :     {
    1075           0 :         maNameList.AppendRecord( xExtName );
    1076           0 :         return static_cast< sal_uInt16 >( nSize + 1 );
    1077             :     }
    1078           0 :     return 0;
    1079             : }
    1080             : 
    1081             : // Cached external cells ======================================================
    1082             : 
    1083           0 : XclExpCrn::XclExpCrn( SCCOL nScCol, SCROW nScRow, const Any& rValue ) :
    1084             :     XclExpRecord( EXC_ID_CRN, 4 ),
    1085             :     mnScCol( nScCol ),
    1086           0 :     mnScRow( nScRow )
    1087             : {
    1088           0 :     maValues.push_back( rValue );
    1089           0 : }
    1090             : 
    1091           0 : bool XclExpCrn::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
    1092             : {
    1093           0 :     if( (nScRow != mnScRow) || (nScCol != static_cast< SCCOL >( mnScCol + maValues.size() )) )
    1094           0 :         return false;
    1095           0 :     maValues.push_back( rValue );
    1096           0 :     return true;
    1097             : }
    1098             : 
    1099           0 : void XclExpCrn::WriteBody( XclExpStream& rStrm )
    1100             : {
    1101           0 :     rStrm   << static_cast< sal_uInt8 >( mnScCol + maValues.size() - 1 )
    1102           0 :             << static_cast< sal_uInt8 >( mnScCol )
    1103           0 :             << static_cast< sal_uInt16 >( mnScRow );
    1104           0 :     for( CachedValues::iterator aIt = maValues.begin(), aEnd = maValues.end(); aIt != aEnd; ++aIt )
    1105             :     {
    1106           0 :         if( aIt->has< bool >() )
    1107           0 :             WriteBool( rStrm, aIt->get< bool >() );
    1108           0 :         else if( aIt->has< double >() )
    1109           0 :             WriteDouble( rStrm, aIt->get< double >() );
    1110           0 :         else if( aIt->has< OUString >() )
    1111           0 :             WriteString( rStrm, aIt->get< OUString >() );
    1112             :         else
    1113           0 :             WriteEmpty( rStrm );
    1114             :     }
    1115           0 : }
    1116             : 
    1117           0 : void XclExpCrn::WriteBool( XclExpStream& rStrm, bool bValue )
    1118             : {
    1119           0 :     rStrm << EXC_CACHEDVAL_BOOL << sal_uInt8( bValue ? 1 : 0);
    1120           0 :     rStrm.WriteZeroBytes( 7 );
    1121           0 : }
    1122             : 
    1123           0 : void XclExpCrn::WriteDouble( XclExpStream& rStrm, double fValue )
    1124             : {
    1125           0 :     if( ::rtl::math::isNan( fValue ) )
    1126             :     {
    1127           0 :         sal_uInt16 nScError = static_cast< sal_uInt16 >( reinterpret_cast< const sal_math_Double* >( &fValue )->nan_parts.fraction_lo );
    1128           0 :         WriteError( rStrm, XclTools::GetXclErrorCode( nScError ) );
    1129             :     }
    1130             :     else
    1131             :     {
    1132           0 :         rStrm << EXC_CACHEDVAL_DOUBLE << fValue;
    1133             :     }
    1134           0 : }
    1135             : 
    1136           0 : void XclExpCrn::WriteString( XclExpStream& rStrm, const OUString& rValue )
    1137             : {
    1138           0 :     rStrm << EXC_CACHEDVAL_STRING << XclExpString( rValue );
    1139           0 : }
    1140             : 
    1141           0 : void XclExpCrn::WriteError( XclExpStream& rStrm, sal_uInt8 nErrCode )
    1142             : {
    1143           0 :     rStrm << EXC_CACHEDVAL_ERROR << nErrCode;
    1144           0 :     rStrm.WriteZeroBytes( 7 );
    1145           0 : }
    1146             : 
    1147           0 : void XclExpCrn::WriteEmpty( XclExpStream& rStrm )
    1148             : {
    1149           0 :     rStrm << EXC_CACHEDVAL_EMPTY;
    1150           0 :     rStrm.WriteZeroBytes( 8 );
    1151           0 : }
    1152             : 
    1153             : // Cached cells of a sheet ====================================================
    1154             : 
    1155           0 : XclExpXct::XclExpXct( const XclExpRoot& rRoot, const OUString& rTabName,
    1156             :         sal_uInt16 nSBTab, ScExternalRefCache::TableTypeRef xCacheTable ) :
    1157             :     XclExpRoot( rRoot ),
    1158             :     mxCacheTable( xCacheTable ),
    1159             :     maBoundRange( ScAddress::INITIALIZE_INVALID ),
    1160             :     maTabName( rTabName ),
    1161           0 :     mnSBTab( nSBTab )
    1162             : {
    1163           0 : }
    1164             : 
    1165           0 : void XclExpXct::StoreCellRange( const ScRange& rRange )
    1166             : {
    1167             :     // #i70418# restrict size of external range to prevent memory overflow
    1168           0 :     if( (rRange.aEnd.Col() - rRange.aStart.Col()) * (rRange.aEnd.Row() - rRange.aStart.Row()) > 1024 )
    1169           0 :         return;
    1170             : 
    1171           0 :     maUsedCells.SetMultiMarkArea( rRange );
    1172           0 :     maBoundRange.ExtendTo( rRange );
    1173             : }
    1174             : 
    1175           0 : void XclExpXct::StoreCell( const ScAddress& rCell, const ::formula::FormulaToken& rToken )
    1176             : {
    1177           0 :     maUsedCells.SetMultiMarkArea( ScRange( rCell ) );
    1178           0 :     maBoundRange.ExtendTo( ScRange( rCell ) );
    1179             :     (void)rToken;
    1180           0 : }
    1181             : 
    1182           0 : void XclExpXct::StoreCellRange( const ScRange& rRange, const ::formula::FormulaToken& rToken )
    1183             : {
    1184           0 :     maUsedCells.SetMultiMarkArea( rRange );
    1185           0 :     maBoundRange.ExtendTo( rRange );
    1186             :     (void)rToken;
    1187           0 : }
    1188             : 
    1189             : namespace {
    1190             : 
    1191           0 : class XclExpCrnList : public XclExpRecordList< XclExpCrn >
    1192             : {
    1193             : public:
    1194             :     /** Inserts the passed value into an existing or new CRN record.
    1195             :         @return  True = value inserted successfully, false = CRN list is full. */
    1196             :     bool                InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue );
    1197             : };
    1198             : 
    1199           0 : bool XclExpCrnList::InsertValue( SCCOL nScCol, SCROW nScRow, const Any& rValue )
    1200             : {
    1201           0 :     RecordRefType xLastRec = GetLastRecord();
    1202           0 :     if( xLastRec && xLastRec->InsertValue( nScCol, nScRow, rValue ) )
    1203           0 :         return true;
    1204           0 :     if( GetSize() == SAL_MAX_UINT16 )
    1205           0 :         return false;
    1206           0 :     AppendNewRecord( new XclExpCrn( nScCol, nScRow, rValue ) );
    1207           0 :     return true;
    1208             : }
    1209             : 
    1210             : } // namespace
    1211             : 
    1212           0 : void XclExpXct::Save( XclExpStream& rStrm )
    1213             : {
    1214           0 :     if( !mxCacheTable )
    1215           0 :         return;
    1216             : 
    1217             :     /*  Get the range of used rows in the cache table. This may help to
    1218             :         optimize building the CRN record list if the cache table does not
    1219             :         contain all referred cells, e.g. if big empty ranges are used in the
    1220             :         formulas. */
    1221           0 :     ::std::pair< SCROW, SCROW > aRowRange = mxCacheTable->getRowRange();
    1222           0 :     if( aRowRange.first >= aRowRange.second )
    1223           0 :         return;
    1224             : 
    1225             :     /*  Crop the bounding range of used cells in this table to Excel limits.
    1226             :         Return if there is no external cell inside these limits. */
    1227           0 :     if( !GetAddressConverter().ValidateRange( maBoundRange, false ) )
    1228           0 :         return;
    1229             : 
    1230             :     /*  Find the resulting row range that needs to be processed. */
    1231           0 :     SCROW nScRow1 = ::std::max( aRowRange.first, maBoundRange.aStart.Row() );
    1232           0 :     SCROW nScRow2 = ::std::min( aRowRange.second - 1, maBoundRange.aEnd.Row() );
    1233           0 :     if( nScRow1 > nScRow2 )
    1234           0 :         return;
    1235             : 
    1236             :     /*  Build and collect all CRN records before writing the XCT record. This
    1237             :         is needed to determine the total number of CRN records which must be
    1238             :         known when writing the XCT record (possibly encrypted, so seeking the
    1239             :         output strem back after writing the CRN records is not an option). */
    1240           0 :     XclExpCrnList aCrnRecs;
    1241           0 :     SvNumberFormatter& rFormatter = GetFormatter();
    1242           0 :     bool bValid = true;
    1243           0 :     for( SCROW nScRow = nScRow1; bValid && (nScRow <= nScRow2); ++nScRow )
    1244             :     {
    1245           0 :         ::std::pair< SCCOL, SCCOL > aColRange = mxCacheTable->getColRange( nScRow );
    1246           0 :         for( SCCOL nScCol = aColRange.first; bValid && (nScCol < aColRange.second); ++nScCol )
    1247             :         {
    1248           0 :             if( maUsedCells.IsCellMarked( nScCol, nScRow, true ) )
    1249             :             {
    1250           0 :                 sal_uInt32 nScNumFmt = 0;
    1251           0 :                 ScExternalRefCache::TokenRef xToken = mxCacheTable->getCell( nScCol, nScRow, &nScNumFmt );
    1252             :                 using namespace ::formula;
    1253           0 :                 if( xToken.get() ) switch( xToken->GetType() )
    1254             :                 {
    1255             :                     case svDouble:
    1256           0 :                         bValid = (rFormatter.GetType( nScNumFmt ) == NUMBERFORMAT_LOGICAL) ?
    1257           0 :                             aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() != 0 ) ) :
    1258           0 :                             aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetDouble() ) );
    1259           0 :                     break;
    1260             :                     case svString:
    1261             :                         // do not save empty strings (empty cells) to cache
    1262           0 :                         if( !xToken->GetString().isEmpty() )
    1263           0 :                             bValid = aCrnRecs.InsertValue( nScCol, nScRow, Any( xToken->GetString().getString() ) );
    1264           0 :                     break;
    1265             :                     default:
    1266           0 :                     break;
    1267           0 :                 }
    1268             :             }
    1269             :         }
    1270             :     }
    1271             : 
    1272             :     // write the XCT record and the list of CRN records
    1273           0 :     rStrm.StartRecord( EXC_ID_XCT, 4 );
    1274           0 :     rStrm << static_cast< sal_uInt16 >( aCrnRecs.GetSize() ) << mnSBTab;
    1275           0 :     rStrm.EndRecord();
    1276           0 :     aCrnRecs.Save( rStrm );
    1277             : }
    1278             : 
    1279             : // External documents (EXTERNSHEET/SUPBOOK), base class =======================
    1280             : 
    1281           0 : XclExpExternSheetBase::XclExpExternSheetBase( const XclExpRoot& rRoot, sal_uInt16 nRecId, sal_uInt32 nRecSize ) :
    1282             :     XclExpRecord( nRecId, nRecSize ),
    1283           0 :     XclExpRoot( rRoot )
    1284             : {
    1285           0 : }
    1286             : 
    1287           0 : XclExpExtNameBuffer& XclExpExternSheetBase::GetExtNameBuffer()
    1288             : {
    1289           0 :     if( !mxExtNameBfr )
    1290           0 :         mxExtNameBfr.reset( new XclExpExtNameBuffer( GetRoot() ) );
    1291           0 :     return *mxExtNameBfr;
    1292             : }
    1293             : 
    1294           0 : void XclExpExternSheetBase::WriteExtNameBuffer( XclExpStream& rStrm )
    1295             : {
    1296           0 :     if( mxExtNameBfr )
    1297           0 :         mxExtNameBfr->Save( rStrm );
    1298           0 : }
    1299             : 
    1300             : // External documents (EXTERNSHEET, BIFF5/BIFF7) ==============================
    1301             : 
    1302           0 : XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, sal_Unicode cCode ) :
    1303           0 :     XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
    1304             : {
    1305           0 :     Init( OUString(cCode) );
    1306           0 : }
    1307             : 
    1308           0 : XclExpExternSheet::XclExpExternSheet( const XclExpRoot& rRoot, const OUString& rTabName ) :
    1309           0 :     XclExpExternSheetBase( rRoot, EXC_ID_EXTERNSHEET )
    1310             : {
    1311             :     // reference to own sheet: \03<sheetname>
    1312           0 :     Init(OUString(EXC_EXTSH_TABNAME) + rTabName);
    1313           0 : }
    1314             : 
    1315           0 : void XclExpExternSheet::Save( XclExpStream& rStrm )
    1316             : {
    1317             :     // EXTERNSHEET record
    1318           0 :     XclExpRecord::Save( rStrm );
    1319             :     // EXTERNNAME records
    1320           0 :     WriteExtNameBuffer( rStrm );
    1321           0 : }
    1322             : 
    1323           0 : void XclExpExternSheet::Init( const OUString& rEncUrl )
    1324             : {
    1325             :     OSL_ENSURE_BIFF( GetBiff() <= EXC_BIFF5 );
    1326           0 :     maTabName.AssignByte( rEncUrl, GetTextEncoding(), EXC_STR_8BITLENGTH );
    1327           0 :     SetRecSize( maTabName.GetSize() );
    1328           0 : }
    1329             : 
    1330           0 : sal_uInt16 XclExpExternSheet::InsertAddIn( const OUString& rName )
    1331             : {
    1332           0 :     return GetExtNameBuffer().InsertAddIn( rName );
    1333             : }
    1334             : 
    1335           0 : void XclExpExternSheet::WriteBody( XclExpStream& rStrm )
    1336             : {
    1337           0 :     sal_uInt8 nNameSize = static_cast< sal_uInt8 >( maTabName.Len() );
    1338             :     // special case: reference to own sheet (starting with '\03') needs wrong string length
    1339           0 :     if( maTabName.GetChar( 0 ) == EXC_EXTSH_TABNAME )
    1340           0 :         --nNameSize;
    1341           0 :     rStrm << nNameSize;
    1342           0 :     maTabName.WriteBuffer( rStrm );
    1343           0 : }
    1344             : 
    1345             : // External document (SUPBOOK, BIFF8) =========================================
    1346             : 
    1347           0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, sal_uInt16 nXclTabCount ) :
    1348             :     XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
    1349             :     meType( EXC_SBTYPE_SELF ),
    1350           0 :     mnXclTabCount( nXclTabCount )
    1351             : {
    1352           0 : }
    1353             : 
    1354           0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot ) :
    1355             :     XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
    1356             :     meType( EXC_SBTYPE_ADDIN ),
    1357           0 :     mnXclTabCount( 1 )
    1358             : {
    1359           0 : }
    1360             : 
    1361           0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const OUString& rUrl, XclSupbookType ) :
    1362             :     XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
    1363             :     maUrl( rUrl ),
    1364             :     maUrlEncoded( rUrl ),
    1365             :     meType( EXC_SBTYPE_EUROTOOL ),
    1366           0 :     mnXclTabCount( 0 )
    1367             : {
    1368           0 :     SetRecSize( 2 + maUrlEncoded.GetSize() );
    1369           0 : }
    1370             : 
    1371             : 
    1372           0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const OUString& rUrl ) :
    1373             :     XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK ),
    1374             :     maUrl( rUrl ),
    1375             :     maUrlEncoded( XclExpUrlHelper::EncodeUrl( rRoot, rUrl ) ),
    1376             :     meType( EXC_SBTYPE_EXTERN ),
    1377           0 :     mnXclTabCount( 0 )
    1378             : {
    1379           0 :     SetRecSize( 2 + maUrlEncoded.GetSize() );
    1380             : 
    1381             :     // We need to create all tables up front to ensure the correct table order.
    1382           0 :     ScExternalRefManager* pRefMgr = rRoot.GetDoc().GetExternalRefManager();
    1383           0 :     sal_uInt16 nFileId = pRefMgr->getExternalFileId( rUrl );
    1384           0 :     ScfStringVec aTabNames;
    1385           0 :     pRefMgr->getAllCachedTableNames( nFileId, aTabNames );
    1386           0 :     for( ScfStringVec::const_iterator aBeg = aTabNames.begin(), aIt = aBeg, aEnd = aTabNames.end(); aIt != aEnd; ++aIt )
    1387           0 :         InsertTabName( *aIt, pRefMgr->getCacheTable( nFileId, aIt - aBeg ) );
    1388           0 : }
    1389             : 
    1390           0 : XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const OUString& rApplic, const OUString& rTopic ) :
    1391             :     XclExpExternSheetBase( rRoot, EXC_ID_SUPBOOK, 4 ),
    1392             :     maUrl( rApplic ),
    1393             :     maDdeTopic( rTopic ),
    1394             :     maUrlEncoded( XclExpUrlHelper::EncodeDde( rApplic, rTopic ) ),
    1395             :     meType( EXC_SBTYPE_SPECIAL ),
    1396           0 :     mnXclTabCount( 0 )
    1397             : {
    1398           0 :     SetRecSize( 2 + maUrlEncoded.GetSize() );
    1399           0 : }
    1400             : 
    1401           0 : bool XclExpSupbook::IsUrlLink( const OUString& rUrl ) const
    1402             : {
    1403           0 :     return (meType == EXC_SBTYPE_EXTERN || meType == EXC_SBTYPE_EUROTOOL) && (maUrl == rUrl);
    1404             : }
    1405             : 
    1406           0 : bool XclExpSupbook::IsDdeLink( const OUString& rApplic, const OUString& rTopic ) const
    1407             : {
    1408           0 :     return (meType == EXC_SBTYPE_SPECIAL) && (maUrl == rApplic) && (maDdeTopic == rTopic);
    1409             : }
    1410             : 
    1411           0 : void XclExpSupbook::FillRefLogEntry( XclExpRefLogEntry& rRefLogEntry,
    1412             :         sal_uInt16 nFirstSBTab, sal_uInt16 nLastSBTab ) const
    1413             : {
    1414           0 :     rRefLogEntry.mpUrl = maUrlEncoded.IsEmpty() ? 0 : &maUrlEncoded;
    1415           0 :     rRefLogEntry.mpFirstTab = GetTabName( nFirstSBTab );
    1416           0 :     rRefLogEntry.mpLastTab = GetTabName( nLastSBTab );
    1417           0 : }
    1418             : 
    1419           0 : void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab )
    1420             : {
    1421           0 :     if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
    1422           0 :         pXct->StoreCellRange( rRange );
    1423           0 : }
    1424             : 
    1425           0 : void XclExpSupbook::StoreCell( sal_uInt16 nSBTab, const ScAddress& rCell, const formula::FormulaToken& rToken )
    1426             : {
    1427           0 :     if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
    1428           0 :         pXct->StoreCell( rCell, rToken );
    1429           0 : }
    1430             : 
    1431           0 : void XclExpSupbook::StoreCellRange( sal_uInt16 nSBTab, const ScRange& rRange, const formula::FormulaToken& rToken )
    1432             : {
    1433             :     // multi-table range is not allowed!
    1434           0 :     if( rRange.aStart.Tab() == rRange.aEnd.Tab() )
    1435           0 :         if( XclExpXct* pXct = maXctList.GetRecord( nSBTab ).get() )
    1436           0 :             pXct->StoreCellRange( rRange, rToken );
    1437           0 : }
    1438             : 
    1439           0 : sal_uInt16 XclExpSupbook::GetTabIndex( const OUString& rTabName ) const
    1440             : {
    1441           0 :     XclExpString aXclName(rTabName);
    1442           0 :     size_t nSize = maXctList.GetSize();
    1443           0 :     for (size_t i = 0; i < nSize; ++i)
    1444             :     {
    1445           0 :         XclExpXctRef aRec = maXctList.GetRecord(i);
    1446           0 :         if (aXclName == aRec->GetTabName())
    1447           0 :             return ulimit_cast<sal_uInt16>(i);
    1448           0 :     }
    1449           0 :     return EXC_NOTAB;
    1450             : }
    1451             : 
    1452           0 : sal_uInt16 XclExpSupbook::GetTabCount() const
    1453             : {
    1454           0 :     return ulimit_cast<sal_uInt16>(maXctList.GetSize());
    1455             : }
    1456             : 
    1457           0 : sal_uInt16 XclExpSupbook::InsertTabName( const OUString& rTabName, ScExternalRefCache::TableTypeRef xCacheTable )
    1458             : {
    1459             :     OSL_ENSURE( meType == EXC_SBTYPE_EXTERN, "XclExpSupbook::InsertTabName - don't insert sheet names here" );
    1460           0 :     sal_uInt16 nSBTab = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
    1461           0 :     XclExpXctRef xXct( new XclExpXct( GetRoot(), rTabName, nSBTab, xCacheTable ) );
    1462           0 :     AddRecSize( xXct->GetTabName().GetSize() );
    1463           0 :     maXctList.AppendRecord( xXct );
    1464           0 :     return nSBTab;
    1465             : }
    1466             : 
    1467           0 : sal_uInt16 XclExpSupbook::InsertAddIn( const OUString& rName )
    1468             : {
    1469           0 :     return GetExtNameBuffer().InsertAddIn( rName );
    1470             : }
    1471             : 
    1472           0 : sal_uInt16 XclExpSupbook::InsertEuroTool( const OUString& rName )
    1473             : {
    1474           0 :     return GetExtNameBuffer().InsertEuroTool( rName );
    1475             : }
    1476             : 
    1477           0 : sal_uInt16 XclExpSupbook::InsertDde( const OUString& rItem )
    1478             : {
    1479           0 :     return GetExtNameBuffer().InsertDde( maUrl, maDdeTopic, rItem );
    1480             : }
    1481             : 
    1482           0 : sal_uInt16 XclExpSupbook::InsertExtName( const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray )
    1483             : {
    1484           0 :     return GetExtNameBuffer().InsertExtName(*this, rName, pArray);
    1485             : }
    1486             : 
    1487           0 : void XclExpSupbook::Save( XclExpStream& rStrm )
    1488             : {
    1489             :     // SUPBOOK record
    1490           0 :     XclExpRecord::Save( rStrm );
    1491             :     // XCT record, CRN records
    1492           0 :     maXctList.Save( rStrm );
    1493             :     // EXTERNNAME records
    1494           0 :     WriteExtNameBuffer( rStrm );
    1495           0 : }
    1496             : 
    1497           0 : const XclExpString* XclExpSupbook::GetTabName( sal_uInt16 nSBTab ) const
    1498             : {
    1499           0 :     XclExpXctRef xXct = maXctList.GetRecord( nSBTab );
    1500           0 :     return xXct ? &xXct->GetTabName() : 0;
    1501             : }
    1502             : 
    1503           0 : void XclExpSupbook::WriteBody( XclExpStream& rStrm )
    1504             : {
    1505           0 :     switch( meType )
    1506             :     {
    1507             :         case EXC_SBTYPE_SELF:
    1508           0 :             rStrm << mnXclTabCount << EXC_SUPB_SELF;
    1509           0 :         break;
    1510             :         case EXC_SBTYPE_EXTERN:
    1511             :         case EXC_SBTYPE_SPECIAL:
    1512             :         case EXC_SBTYPE_EUROTOOL:
    1513             :         {
    1514           0 :             sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXctList.GetSize() );
    1515           0 :             rStrm << nCount << maUrlEncoded;
    1516             : 
    1517           0 :             for( size_t nPos = 0, nSize = maXctList.GetSize(); nPos < nSize; ++nPos )
    1518           0 :                 rStrm << maXctList.GetRecord( nPos )->GetTabName();
    1519             :         }
    1520           0 :         break;
    1521             :         case EXC_SBTYPE_ADDIN:
    1522           0 :             rStrm << mnXclTabCount << EXC_SUPB_ADDIN;
    1523           0 :         break;
    1524             :         default:
    1525             :             OSL_FAIL( "XclExpSupbook::WriteBody - unknown SUPBOOK type" );
    1526             :     }
    1527           0 : }
    1528             : 
    1529             : // All SUPBOOKS in a document =================================================
    1530             : 
    1531           0 : XclExpSupbookBuffer::XclExpSupbookBuffer( const XclExpRoot& rRoot ) :
    1532             :     XclExpRoot( rRoot ),
    1533             :     mnOwnDocSB( SAL_MAX_UINT16 ),
    1534           0 :     mnAddInSB( SAL_MAX_UINT16 )
    1535             : {
    1536           0 :     XclExpTabInfo& rTabInfo = GetTabInfo();
    1537           0 :     sal_uInt16 nXclCnt = rTabInfo.GetXclTabCount();
    1538           0 :     sal_uInt16 nCodeCnt = static_cast< sal_uInt16 >( GetExtDocOptions().GetCodeNameCount() );
    1539           0 :     size_t nCount = nXclCnt + rTabInfo.GetXclExtTabCount();
    1540             : 
    1541             :     OSL_ENSURE( nCount > 0, "XclExpSupbookBuffer::XclExpSupbookBuffer - no sheets to export" );
    1542           0 :     if( nCount )
    1543             :     {
    1544           0 :         maSBIndexVec.resize( nCount );
    1545             : 
    1546             :         // self-ref SUPBOOK first of list
    1547           0 :         XclExpSupbookRef xSupbook( new XclExpSupbook( GetRoot(), ::std::max( nXclCnt, nCodeCnt ) ) );
    1548           0 :         mnOwnDocSB = Append( xSupbook );
    1549           0 :         for( sal_uInt16 nXclTab = 0; nXclTab < nXclCnt; ++nXclTab )
    1550           0 :             maSBIndexVec[ nXclTab ].Set( mnOwnDocSB, nXclTab );
    1551             :     }
    1552           0 : }
    1553             : 
    1554           0 : XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFirstXclTab, sal_uInt16 nLastXclTab,
    1555             :         XclExpRefLogEntry* pRefLogEntry ) const
    1556             : {
    1557           0 :     XclExpXti aXti;
    1558           0 :     size_t nSize = maSBIndexVec.size();
    1559           0 :     if( (nFirstXclTab < nSize) && (nLastXclTab < nSize) )
    1560             :     {
    1561             :         // index of the SUPBOOK record
    1562           0 :         aXti.mnSupbook = maSBIndexVec[ nFirstXclTab ].mnSupbook;
    1563             : 
    1564             :         // all sheets in the same supbook?
    1565           0 :         bool bSameSB = true;
    1566           0 :         for( sal_uInt16 nXclTab = nFirstXclTab + 1; bSameSB && (nXclTab <= nLastXclTab); ++nXclTab )
    1567             :         {
    1568           0 :             bSameSB = maSBIndexVec[ nXclTab ].mnSupbook == aXti.mnSupbook;
    1569           0 :             if( !bSameSB )
    1570           0 :                 nLastXclTab = nXclTab - 1;
    1571             :         }
    1572           0 :         aXti.mnFirstSBTab = maSBIndexVec[ nFirstXclTab ].mnSBTab;
    1573           0 :         aXti.mnLastSBTab = maSBIndexVec[ nLastXclTab ].mnSBTab;
    1574             : 
    1575             :         // fill external reference log entry (for change tracking)
    1576           0 :         if( pRefLogEntry )
    1577             :         {
    1578           0 :             pRefLogEntry->mnFirstXclTab = nFirstXclTab;
    1579           0 :             pRefLogEntry->mnLastXclTab = nLastXclTab;
    1580           0 :             XclExpSupbookRef xSupbook = maSupbookList.GetRecord( aXti.mnSupbook );
    1581           0 :             if( xSupbook )
    1582           0 :                 xSupbook->FillRefLogEntry( *pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab );
    1583           0 :         }
    1584             :     }
    1585             :     else
    1586             :     {
    1587             :         // special range, i.e. for deleted sheets or add-ins
    1588           0 :         aXti.mnSupbook = mnOwnDocSB;
    1589           0 :         aXti.mnFirstSBTab = nFirstXclTab;
    1590           0 :         aXti.mnLastSBTab = nLastXclTab;
    1591             :     }
    1592             : 
    1593           0 :     return aXti;
    1594             : }
    1595             : 
    1596           0 : void XclExpSupbookBuffer::StoreCellRange( const ScRange& rRange )
    1597             : {
    1598           0 :     sal_uInt16 nXclTab = GetTabInfo().GetXclTab( rRange.aStart.Tab() );
    1599           0 :     if( nXclTab < maSBIndexVec.size() )
    1600             :     {
    1601           0 :         const XclExpSBIndex& rSBIndex = maSBIndexVec[ nXclTab ];
    1602           0 :         XclExpSupbookRef xSupbook = maSupbookList.GetRecord( rSBIndex.mnSupbook );
    1603             :         OSL_ENSURE( xSupbook , "XclExpSupbookBuffer::StoreCellRange - missing SUPBOOK record" );
    1604           0 :         if( xSupbook )
    1605           0 :             xSupbook->StoreCellRange( rRange, rSBIndex.mnSBTab );
    1606             :     }
    1607           0 : }
    1608             : 
    1609             : namespace {
    1610             : 
    1611             : class FindSBIndexEntry
    1612             : {
    1613             : public:
    1614           0 :     explicit FindSBIndexEntry(sal_uInt16 nSupbookId, sal_uInt16 nTabId) :
    1615           0 :         mnSupbookId(nSupbookId), mnTabId(nTabId) {}
    1616             : 
    1617           0 :     bool operator()(const XclExpSupbookBuffer::XclExpSBIndex& r) const
    1618             :     {
    1619           0 :         return mnSupbookId == r.mnSupbook && mnTabId == r.mnSBTab;
    1620             :     }
    1621             : 
    1622             : private:
    1623             :     sal_uInt16 mnSupbookId;
    1624             :     sal_uInt16 mnTabId;
    1625             : };
    1626             : 
    1627             : }
    1628             : 
    1629           0 : void XclExpSupbookBuffer::StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell )
    1630             : {
    1631           0 :     ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
    1632           0 :     const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
    1633           0 :     if (!pUrl)
    1634           0 :         return;
    1635             : 
    1636           0 :     XclExpSupbookRef xSupbook;
    1637             :     sal_uInt16 nSupbookId;
    1638           0 :     if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
    1639             :     {
    1640           0 :         xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
    1641           0 :         nSupbookId = Append(xSupbook);
    1642             :     }
    1643             : 
    1644           0 :     ScExternalRefCache::TokenRef pToken = pRefMgr->getSingleRefToken(nFileId, rTabName, rCell, NULL, NULL);
    1645           0 :     if (!pToken.get())
    1646           0 :         return;
    1647             : 
    1648           0 :     sal_uInt16 nSheetId = xSupbook->GetTabIndex(rTabName);
    1649           0 :     if (nSheetId == EXC_NOTAB)
    1650             :         // specified table name not found in this SUPBOOK.
    1651           0 :         return;
    1652             : 
    1653           0 :     FindSBIndexEntry f(nSupbookId, nSheetId);
    1654           0 :     XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
    1655           0 :     XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
    1656           0 :     if (itr == itrEnd)
    1657             :     {
    1658           0 :         maSBIndexVec.push_back(XclExpSBIndex());
    1659           0 :         XclExpSBIndex& r = maSBIndexVec.back();
    1660           0 :         r.mnSupbook = nSupbookId;
    1661           0 :         r.mnSBTab   = nSheetId;
    1662             :     }
    1663             : 
    1664           0 :     xSupbook->StoreCell(nSheetId, rCell, *pToken);
    1665             : }
    1666             : 
    1667           0 : void XclExpSupbookBuffer::StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange )
    1668             : {
    1669           0 :     ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
    1670           0 :     const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
    1671           0 :     if (!pUrl)
    1672           0 :         return;
    1673             : 
    1674           0 :     XclExpSupbookRef xSupbook;
    1675             :     sal_uInt16 nSupbookId;
    1676           0 :     if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
    1677             :     {
    1678           0 :         xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
    1679           0 :         nSupbookId = Append(xSupbook);
    1680             :     }
    1681             : 
    1682           0 :     SCTAB nTabCount = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
    1683             : 
    1684             :     // If this is a multi-table range, get token for each table.
    1685             :     using namespace ::formula;
    1686           0 :     vector<FormulaToken*> aMatrixList;
    1687           0 :     aMatrixList.reserve(nTabCount);
    1688             : 
    1689             :     // This is a new'ed instance, so we must manage its life cycle here.
    1690           0 :     ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, rRange, NULL);
    1691           0 :     if (!pArray.get())
    1692           0 :         return;
    1693             : 
    1694           0 :     for (FormulaToken* p = pArray->First(); p; p = pArray->Next())
    1695             :     {
    1696           0 :         if (p->GetType() == svMatrix)
    1697           0 :             aMatrixList.push_back(p);
    1698           0 :         else if (p->GetOpCode() != ocSep)
    1699             :         {
    1700             :             // This is supposed to be ocSep!!!
    1701           0 :             return;
    1702             :         }
    1703             :     }
    1704             : 
    1705           0 :     if (aMatrixList.size() != static_cast<size_t>(nTabCount))
    1706             :     {
    1707             :         // matrix size mis-match !
    1708           0 :         return;
    1709             :     }
    1710             : 
    1711           0 :     sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
    1712             : 
    1713           0 :     ScRange aRange(rRange);
    1714           0 :     aRange.aStart.SetTab(0);
    1715           0 :     aRange.aEnd.SetTab(0);
    1716           0 :     for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
    1717             :     {
    1718           0 :         sal_uInt16 nSheetId = nFirstSheetId + static_cast<sal_uInt16>(nTab);
    1719           0 :         FindSBIndexEntry f(nSupbookId, nSheetId);
    1720           0 :         XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
    1721           0 :         XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
    1722           0 :         if (itr == itrEnd)
    1723             :         {
    1724           0 :             maSBIndexVec.push_back(XclExpSBIndex());
    1725           0 :             XclExpSBIndex& r = maSBIndexVec.back();
    1726           0 :             r.mnSupbook = nSupbookId;
    1727           0 :             r.mnSBTab   = nSheetId;
    1728             :         }
    1729             : 
    1730           0 :         xSupbook->StoreCellRange(nSheetId, aRange, *aMatrixList[nTab]);
    1731           0 :     }
    1732             : }
    1733             : 
    1734           0 : bool XclExpSupbookBuffer::InsertAddIn(
    1735             :         sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const OUString& rName )
    1736             : {
    1737           0 :     XclExpSupbookRef xSupbook;
    1738           0 :     if( mnAddInSB == SAL_MAX_UINT16 )
    1739             :     {
    1740           0 :         xSupbook.reset( new XclExpSupbook( GetRoot() ) );
    1741           0 :         mnAddInSB = Append( xSupbook );
    1742             :     }
    1743             :     else
    1744           0 :         xSupbook = maSupbookList.GetRecord( mnAddInSB );
    1745             :     OSL_ENSURE( xSupbook, "XclExpSupbookBuffer::InsertAddin - missing add-in supbook" );
    1746           0 :     rnSupbook = mnAddInSB;
    1747           0 :     rnExtName = xSupbook->InsertAddIn( rName );
    1748           0 :     return rnExtName > 0;
    1749             : }
    1750             : 
    1751           0 : bool XclExpSupbookBuffer::InsertEuroTool(
    1752             :         sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const OUString& rName )
    1753             : {
    1754           0 :     XclExpSupbookRef xSupbook;
    1755           0 :     OUString aUrl( "\001\010EUROTOOL.XLA" );
    1756           0 :     if( !GetSupbookUrl( xSupbook, rnSupbook, aUrl ) )
    1757             :     {
    1758           0 :         xSupbook.reset( new XclExpSupbook( GetRoot(), aUrl, EXC_SBTYPE_EUROTOOL ) );
    1759           0 :         rnSupbook = Append( xSupbook );
    1760             :     }
    1761           0 :     rnExtName = xSupbook->InsertEuroTool( rName );
    1762           0 :     return rnExtName > 0;
    1763             : }
    1764             : 
    1765           0 : bool XclExpSupbookBuffer::InsertDde(
    1766             :         sal_uInt16& rnSupbook, sal_uInt16& rnExtName,
    1767             :         const OUString& rApplic, const OUString& rTopic, const OUString& rItem )
    1768             : {
    1769           0 :     XclExpSupbookRef xSupbook;
    1770           0 :     if( !GetSupbookDde( xSupbook, rnSupbook, rApplic, rTopic ) )
    1771             :     {
    1772           0 :         xSupbook.reset( new XclExpSupbook( GetRoot(), rApplic, rTopic ) );
    1773           0 :         rnSupbook = Append( xSupbook );
    1774             :     }
    1775           0 :     rnExtName = xSupbook->InsertDde( rItem );
    1776           0 :     return rnExtName > 0;
    1777             : }
    1778             : 
    1779           0 : bool XclExpSupbookBuffer::InsertExtName(
    1780             :         sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const OUString& rUrl,
    1781             :         const OUString& rName, const ScExternalRefCache::TokenArrayRef pArray )
    1782             : {
    1783           0 :     XclExpSupbookRef xSupbook;
    1784           0 :     if (!GetSupbookUrl(xSupbook, rnSupbook, rUrl))
    1785             :     {
    1786           0 :         xSupbook.reset( new XclExpSupbook(GetRoot(), rUrl) );
    1787           0 :         rnSupbook = Append(xSupbook);
    1788             :     }
    1789           0 :     rnExtName = xSupbook->InsertExtName(rName, pArray);
    1790           0 :     return rnExtName > 0;
    1791             : }
    1792             : 
    1793           0 : XclExpXti XclExpSupbookBuffer::GetXti( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
    1794             :                                        XclExpRefLogEntry* pRefLogEntry )
    1795             : {
    1796           0 :     XclExpXti aXti(0, EXC_NOTAB, EXC_NOTAB);
    1797           0 :     ScExternalRefManager* pRefMgr = GetDoc().GetExternalRefManager();
    1798           0 :     const OUString* pUrl = pRefMgr->getExternalFileName(nFileId);
    1799           0 :     if (!pUrl)
    1800           0 :         return aXti;
    1801             : 
    1802           0 :     XclExpSupbookRef xSupbook;
    1803             :     sal_uInt16 nSupbookId;
    1804           0 :     if (!GetSupbookUrl(xSupbook, nSupbookId, *pUrl))
    1805             :     {
    1806           0 :         xSupbook.reset(new XclExpSupbook(GetRoot(), *pUrl));
    1807           0 :         nSupbookId = Append(xSupbook);
    1808             :     }
    1809           0 :     aXti.mnSupbook = nSupbookId;
    1810             : 
    1811           0 :     sal_uInt16 nFirstSheetId = xSupbook->GetTabIndex(rTabName);
    1812           0 :     if (nFirstSheetId == EXC_NOTAB)
    1813             :     {
    1814             :         // first sheet not found in SUPBOOK.
    1815           0 :         return aXti;
    1816             :     }
    1817           0 :     sal_uInt16 nSheetCount = xSupbook->GetTabCount();
    1818           0 :     for (sal_uInt16 i = 0; i < nXclTabSpan; ++i)
    1819             :     {
    1820           0 :         sal_uInt16 nSheetId = nFirstSheetId + i;
    1821           0 :         if (nSheetId >= nSheetCount)
    1822           0 :             return aXti;
    1823             : 
    1824           0 :         FindSBIndexEntry f(nSupbookId, nSheetId);
    1825           0 :         XclExpSBIndexVec::iterator itrEnd = maSBIndexVec.end();
    1826           0 :         XclExpSBIndexVec::const_iterator itr = find_if(maSBIndexVec.begin(), itrEnd, f);
    1827           0 :         if (itr == itrEnd)
    1828             :         {
    1829           0 :             maSBIndexVec.push_back(XclExpSBIndex());
    1830           0 :             XclExpSBIndex& r = maSBIndexVec.back();
    1831           0 :             r.mnSupbook = nSupbookId;
    1832           0 :             r.mnSBTab   = nSheetId;
    1833             :         }
    1834           0 :         if (i == 0)
    1835           0 :             aXti.mnFirstSBTab = nSheetId;
    1836           0 :         if (i == nXclTabSpan - 1)
    1837           0 :             aXti.mnLastSBTab = nSheetId;
    1838             :     }
    1839             : 
    1840           0 :     if (pRefLogEntry)
    1841             :     {
    1842           0 :         pRefLogEntry->mnFirstXclTab = 0;
    1843           0 :         pRefLogEntry->mnLastXclTab  = 0;
    1844           0 :         if (xSupbook)
    1845           0 :             xSupbook->FillRefLogEntry(*pRefLogEntry, aXti.mnFirstSBTab, aXti.mnLastSBTab);
    1846             :     }
    1847             : 
    1848           0 :     return aXti;
    1849             : }
    1850             : 
    1851           0 : void XclExpSupbookBuffer::Save( XclExpStream& rStrm )
    1852             : {
    1853           0 :     maSupbookList.Save( rStrm );
    1854           0 : }
    1855             : 
    1856           0 : bool XclExpSupbookBuffer::GetSupbookUrl(
    1857             :         XclExpSupbookRef& rxSupbook, sal_uInt16& rnIndex, const OUString& rUrl ) const
    1858             : {
    1859           0 :     for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
    1860             :     {
    1861           0 :         rxSupbook = maSupbookList.GetRecord( nPos );
    1862           0 :         if( rxSupbook->IsUrlLink( rUrl ) )
    1863             :         {
    1864           0 :             rnIndex = ulimit_cast< sal_uInt16 >( nPos );
    1865           0 :             return true;
    1866             :         }
    1867             :     }
    1868           0 :     return false;
    1869             : }
    1870             : 
    1871           0 : bool XclExpSupbookBuffer::GetSupbookDde( XclExpSupbookRef& rxSupbook,
    1872             :         sal_uInt16& rnIndex, const OUString& rApplic, const OUString& rTopic ) const
    1873             : {
    1874           0 :     for( size_t nPos = 0, nSize = maSupbookList.GetSize(); nPos < nSize; ++nPos )
    1875             :     {
    1876           0 :         rxSupbook = maSupbookList.GetRecord( nPos );
    1877           0 :         if( rxSupbook->IsDdeLink( rApplic, rTopic ) )
    1878             :         {
    1879           0 :             rnIndex = ulimit_cast< sal_uInt16 >( nPos );
    1880           0 :             return true;
    1881             :         }
    1882             :     }
    1883           0 :     return false;
    1884             : }
    1885             : 
    1886           0 : sal_uInt16 XclExpSupbookBuffer::Append( XclExpSupbookRef xSupbook )
    1887             : {
    1888           0 :     maSupbookList.AppendRecord( xSupbook );
    1889           0 :     return ulimit_cast< sal_uInt16 >( maSupbookList.GetSize() - 1 );
    1890             : }
    1891             : 
    1892             : // Export link manager ========================================================
    1893             : 
    1894           0 : XclExpLinkManagerImpl::XclExpLinkManagerImpl( const XclExpRoot& rRoot ) :
    1895           0 :     XclExpRoot( rRoot )
    1896             : {
    1897           0 : }
    1898             : 
    1899           0 : XclExpLinkManagerImpl5::XclExpLinkManagerImpl5( const XclExpRoot& rRoot ) :
    1900           0 :     XclExpLinkManagerImpl( rRoot )
    1901             : {
    1902           0 : }
    1903             : 
    1904           0 : void XclExpLinkManagerImpl5::FindExtSheet(
    1905             :         sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
    1906             :         SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
    1907             : {
    1908           0 :     FindInternal( rnExtSheet, rnFirstXclTab, nFirstScTab );
    1909           0 :     if( (rnFirstXclTab == EXC_TAB_DELETED) || (nFirstScTab == nLastScTab) )
    1910             :     {
    1911           0 :         rnLastXclTab = rnFirstXclTab;
    1912             :     }
    1913             :     else
    1914             :     {
    1915             :         sal_uInt16 nDummyExtSheet;
    1916           0 :         FindInternal( nDummyExtSheet, rnLastXclTab, nLastScTab );
    1917             :     }
    1918             : 
    1919             :     (void)pRefLogEntry;     // avoid compiler warning
    1920             :     OSL_ENSURE( !pRefLogEntry, "XclExpLinkManagerImpl5::FindExtSheet - fill reflog entry not implemented" );
    1921           0 : }
    1922             : 
    1923           0 : sal_uInt16 XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode )
    1924             : {
    1925             :     sal_uInt16 nExtSheet;
    1926           0 :     FindInternal( nExtSheet, cCode );
    1927           0 :     return nExtSheet;
    1928             : }
    1929             : 
    1930           0 : void XclExpLinkManagerImpl5::FindExtSheet(
    1931             :     sal_uInt16 /*nFileId*/, const OUString& /*rTabName*/, sal_uInt16 /*nXclTabSpan*/,
    1932             :     sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnFirstSBTab*/, sal_uInt16& /*rnLastSBTab*/,
    1933             :     XclExpRefLogEntry* /*pRefLogEntry*/ )
    1934             : {
    1935             :     // not implemented
    1936           0 : }
    1937             : 
    1938           0 : void XclExpLinkManagerImpl5::StoreCellRange( const ScSingleRefData& /*rRef1*/, const ScSingleRefData& /*rRef2*/, const ScAddress& /*rPos*/ )
    1939             : {
    1940             :     // not implemented
    1941           0 : }
    1942             : 
    1943           0 : void XclExpLinkManagerImpl5::StoreCell( sal_uInt16 /*nFileId*/, const OUString& /*rTabName*/, const ScAddress& /*rPos*/ )
    1944             : {
    1945             :     // not implemented
    1946           0 : }
    1947             : 
    1948           0 : void XclExpLinkManagerImpl5::StoreCellRange( sal_uInt16 /*nFileId*/, const OUString& /*rTabName*/, const ScRange& /*rRange*/ )
    1949             : {
    1950             :     // not implemented
    1951           0 : }
    1952             : 
    1953           0 : bool XclExpLinkManagerImpl5::InsertAddIn(
    1954             :         sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
    1955             : {
    1956           0 :     XclExpExtSheetRef xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_ADDIN );
    1957           0 :     if( xExtSheet )
    1958             :     {
    1959           0 :         rnExtName = xExtSheet->InsertAddIn( rName );
    1960           0 :         return rnExtName > 0;
    1961             :     }
    1962           0 :     return false;
    1963             : }
    1964             : 
    1965           0 : bool XclExpLinkManagerImpl5::InsertEuroTool(
    1966             :          sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const OUString& /*rName*/ )
    1967             : {
    1968           0 :      return false;
    1969             : }
    1970             : 
    1971             : 
    1972           0 : bool XclExpLinkManagerImpl5::InsertDde(
    1973             :         sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/,
    1974             :         const OUString& /*rApplic*/, const OUString& /*rTopic*/, const OUString& /*rItem*/ )
    1975             : {
    1976             :     // not implemented
    1977           0 :     return false;
    1978             : }
    1979             : 
    1980           0 : bool XclExpLinkManagerImpl5::InsertExtName(
    1981             :         sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const OUString& /*rUrl*/,
    1982             :         const OUString& /*rName*/, const ScExternalRefCache::TokenArrayRef /*pArray*/ )
    1983             : {
    1984             :     // not implemented
    1985           0 :     return false;
    1986             : }
    1987             : 
    1988           0 : void XclExpLinkManagerImpl5::Save( XclExpStream& rStrm )
    1989             : {
    1990           0 :     if( sal_uInt16 nExtSheetCount = GetExtSheetCount() )
    1991             :     {
    1992             :         // EXTERNCOUNT record
    1993           0 :         XclExpUInt16Record( EXC_ID_EXTERNCOUNT, nExtSheetCount ).Save( rStrm );
    1994             :         // list of EXTERNSHEET records with EXTERNNAME, XCT, CRN records
    1995           0 :         maExtSheetList.Save( rStrm );
    1996             :     }
    1997           0 : }
    1998             : 
    1999           0 : sal_uInt16 XclExpLinkManagerImpl5::GetExtSheetCount() const
    2000             : {
    2001           0 :     return static_cast< sal_uInt16 >( maExtSheetList.GetSize() );
    2002             : }
    2003             : 
    2004           0 : sal_uInt16 XclExpLinkManagerImpl5::AppendInternal( XclExpExtSheetRef xExtSheet )
    2005             : {
    2006           0 :     if( GetExtSheetCount() < 0x7FFF )
    2007             :     {
    2008           0 :         maExtSheetList.AppendRecord( xExtSheet );
    2009             :         // return negated one-based EXTERNSHEET index (i.e. 0xFFFD for 3rd record)
    2010           0 :         return static_cast< sal_uInt16 >( -GetExtSheetCount() );
    2011             :     }
    2012           0 :     return 0;
    2013             : }
    2014             : 
    2015           0 : void XclExpLinkManagerImpl5::CreateInternal()
    2016             : {
    2017           0 :     if( maIntTabMap.empty() )
    2018             :     {
    2019             :         // create EXTERNSHEET records for all internal exported sheets
    2020           0 :         XclExpTabInfo& rTabInfo = GetTabInfo();
    2021           0 :         for( SCTAB nScTab = 0, nScCnt = rTabInfo.GetScTabCount(); nScTab < nScCnt; ++nScTab )
    2022             :         {
    2023           0 :             if( rTabInfo.IsExportTab( nScTab ) )
    2024             :             {
    2025           0 :                 XclExpExtSheetRef xRec;
    2026           0 :                 if( nScTab == GetCurrScTab() )
    2027           0 :                     xRec.reset( new XclExpExternSheet( GetRoot(), EXC_EXTSH_OWNTAB ) );
    2028             :                 else
    2029           0 :                     xRec.reset( new XclExpExternSheet( GetRoot(), rTabInfo.GetScTabName( nScTab ) ) );
    2030           0 :                 maIntTabMap[ nScTab ] = AppendInternal( xRec );
    2031             :             }
    2032             :         }
    2033             :     }
    2034           0 : }
    2035             : 
    2036           0 : XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::GetInternal( sal_uInt16 nExtSheet )
    2037             : {
    2038           0 :     return maExtSheetList.GetRecord( static_cast< sal_uInt16 >( -nExtSheet - 1 ) );
    2039             : }
    2040             : 
    2041           0 : XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
    2042             :         sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab, SCTAB nScTab )
    2043             : {
    2044             :     // create internal EXTERNSHEET records on demand
    2045           0 :     CreateInternal();
    2046             : 
    2047             :     // try to find an EXTERNSHEET record - if not, return a "deleted sheet" reference
    2048           0 :     XclExpExtSheetRef xExtSheet;
    2049           0 :     XclExpIntTabMap::const_iterator aIt = maIntTabMap.find( nScTab );
    2050           0 :     if( aIt == maIntTabMap.end() )
    2051             :     {
    2052           0 :         xExtSheet = FindInternal( rnExtSheet, EXC_EXTSH_OWNDOC );
    2053           0 :         rnXclTab = EXC_TAB_DELETED;
    2054             :     }
    2055             :     else
    2056             :     {
    2057           0 :         rnExtSheet = aIt->second;
    2058           0 :         xExtSheet = GetInternal( rnExtSheet );
    2059           0 :         rnXclTab = GetTabInfo().GetXclTab( nScTab );
    2060             :     }
    2061           0 :     return xExtSheet;
    2062             : }
    2063             : 
    2064           0 : XclExpLinkManagerImpl5::XclExpExtSheetRef XclExpLinkManagerImpl5::FindInternal(
    2065             :     sal_uInt16& rnExtSheet, sal_Unicode cCode )
    2066             : {
    2067           0 :     XclExpExtSheetRef xExtSheet;
    2068           0 :     XclExpCodeMap::const_iterator aIt = maCodeMap.find( cCode );
    2069           0 :     if( aIt == maCodeMap.end() )
    2070             :     {
    2071           0 :         xExtSheet.reset( new XclExpExternSheet( GetRoot(), cCode ) );
    2072           0 :         rnExtSheet = maCodeMap[ cCode ] = AppendInternal( xExtSheet );
    2073             :     }
    2074             :     else
    2075             :     {
    2076           0 :         rnExtSheet = aIt->second;
    2077           0 :         xExtSheet = GetInternal( rnExtSheet );
    2078             :     }
    2079           0 :     return xExtSheet;
    2080             : }
    2081             : 
    2082           0 : XclExpLinkManagerImpl8::XclExpLinkManagerImpl8( const XclExpRoot& rRoot ) :
    2083             :     XclExpLinkManagerImpl( rRoot ),
    2084           0 :     maSBBuffer( rRoot )
    2085             : {
    2086           0 : }
    2087             : 
    2088           0 : void XclExpLinkManagerImpl8::FindExtSheet(
    2089             :         sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
    2090             :         SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
    2091             : {
    2092           0 :     XclExpTabInfo& rTabInfo = GetTabInfo();
    2093           0 :     rnFirstXclTab = rTabInfo.GetXclTab( nFirstScTab );
    2094           0 :     rnLastXclTab = rTabInfo.GetXclTab( nLastScTab );
    2095           0 :     rnExtSheet = InsertXti( maSBBuffer.GetXti( rnFirstXclTab, rnLastXclTab, pRefLogEntry ) );
    2096           0 : }
    2097             : 
    2098           0 : sal_uInt16 XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode )
    2099             : {
    2100             :     (void)cCode;    // avoid compiler warning
    2101             :     OSL_ENSURE( (cCode == EXC_EXTSH_OWNDOC) || (cCode == EXC_EXTSH_ADDIN),
    2102             :         "XclExpLinkManagerImpl8::FindExtSheet - unknown externsheet code" );
    2103           0 :     return InsertXti( maSBBuffer.GetXti( EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
    2104             : }
    2105             : 
    2106           0 : void XclExpLinkManagerImpl8::FindExtSheet(
    2107             :     sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
    2108             :     sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
    2109             :     XclExpRefLogEntry* pRefLogEntry )
    2110             : {
    2111           0 :     XclExpXti aXti = maSBBuffer.GetXti(nFileId, rTabName, nXclTabSpan, pRefLogEntry);
    2112           0 :     rnExtSheet = InsertXti(aXti);
    2113           0 :     rnFirstSBTab = aXti.mnFirstSBTab;
    2114           0 :     rnLastSBTab  = aXti.mnLastSBTab;
    2115           0 : }
    2116             : 
    2117           0 : void XclExpLinkManagerImpl8::StoreCellRange( const ScSingleRefData& rRef1, const ScSingleRefData& rRef2, const ScAddress& rPos )
    2118             : {
    2119           0 :     ScAddress aAbs1 = rRef1.toAbs(rPos);
    2120           0 :     ScAddress aAbs2 = rRef2.toAbs(rPos);
    2121           0 :     if (!rRef1.IsDeleted() && !rRef2.IsDeleted() && (aAbs1.Tab() >= 0) && (aAbs2.Tab() >= 0))
    2122             :     {
    2123           0 :         const XclExpTabInfo& rTabInfo = GetTabInfo();
    2124           0 :         SCTAB nFirstScTab = aAbs1.Tab();
    2125           0 :         SCTAB nLastScTab = aAbs2.Tab();
    2126           0 :         ScRange aRange(aAbs1.Col(), aAbs1.Row(), 0, aAbs2.Col(), aAbs2.Row(), 0);
    2127           0 :         for (SCTAB nScTab = nFirstScTab; nScTab <= nLastScTab; ++nScTab)
    2128             :         {
    2129           0 :             if( rTabInfo.IsExternalTab( nScTab ) )
    2130             :             {
    2131           0 :                 aRange.aStart.SetTab( nScTab );
    2132           0 :                 aRange.aEnd.SetTab( nScTab );
    2133           0 :                 maSBBuffer.StoreCellRange( aRange );
    2134             :             }
    2135             :         }
    2136             :     }
    2137           0 : }
    2138             : 
    2139           0 : void XclExpLinkManagerImpl8::StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos )
    2140             : {
    2141           0 :     maSBBuffer.StoreCell(nFileId, rTabName, rPos);
    2142           0 : }
    2143             : 
    2144           0 : void XclExpLinkManagerImpl8::StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange )
    2145             : {
    2146           0 :     maSBBuffer.StoreCellRange(nFileId, rTabName, rRange);
    2147           0 : }
    2148             : 
    2149           0 : bool XclExpLinkManagerImpl8::InsertAddIn(
    2150             :         sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
    2151             : {
    2152             :     sal_uInt16 nSupbook;
    2153           0 :     if( maSBBuffer.InsertAddIn( nSupbook, rnExtName, rName ) )
    2154             :     {
    2155           0 :         rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
    2156           0 :         return true;
    2157             :     }
    2158           0 :     return false;
    2159             : }
    2160             : 
    2161           0 : bool XclExpLinkManagerImpl8::InsertEuroTool(
    2162             :          sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
    2163             : {
    2164             :     sal_uInt16 nSupbook;
    2165           0 :     if( maSBBuffer.InsertEuroTool( nSupbook, rnExtName, rName ) )
    2166             :     {
    2167           0 :         rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
    2168           0 :         return true;
    2169             :     }
    2170           0 :     return false;
    2171             : }
    2172             : 
    2173             : 
    2174           0 : bool XclExpLinkManagerImpl8::InsertDde(
    2175             :         sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
    2176             :         const OUString& rApplic, const OUString& rTopic, const OUString& rItem )
    2177             : {
    2178             :     sal_uInt16 nSupbook;
    2179           0 :     if( maSBBuffer.InsertDde( nSupbook, rnExtName, rApplic, rTopic, rItem ) )
    2180             :     {
    2181           0 :         rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
    2182           0 :         return true;
    2183             :     }
    2184           0 :     return false;
    2185             : }
    2186             : 
    2187           0 : bool XclExpLinkManagerImpl8::InsertExtName( sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
    2188             :         const OUString& rName, const OUString& rUrl, const ScExternalRefCache::TokenArrayRef pArray )
    2189             : {
    2190             :     sal_uInt16 nSupbook;
    2191           0 :     if( maSBBuffer.InsertExtName( nSupbook, rnExtName, rUrl, rName, pArray ) )
    2192             :     {
    2193           0 :         rnExtSheet = InsertXti( XclExpXti( nSupbook, EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
    2194           0 :         return true;
    2195             :     }
    2196           0 :     return false;
    2197             : }
    2198             : 
    2199           0 : void XclExpLinkManagerImpl8::Save( XclExpStream& rStrm )
    2200             : {
    2201           0 :     if( !maXtiVec.empty() )
    2202             :     {
    2203             :         // SUPBOOKs, XCTs, CRNs, EXTERNNAMEs
    2204           0 :         maSBBuffer.Save( rStrm );
    2205             : 
    2206             :         // EXTERNSHEET
    2207           0 :         sal_uInt16 nCount = ulimit_cast< sal_uInt16 >( maXtiVec.size() );
    2208           0 :         rStrm.StartRecord( EXC_ID_EXTERNSHEET, 2 + 6 * nCount );
    2209           0 :         rStrm << nCount;
    2210           0 :         rStrm.SetSliceSize( 6 );
    2211           0 :         for( XclExpXtiVec::const_iterator aIt = maXtiVec.begin(), aEnd = maXtiVec.end(); aIt != aEnd; ++aIt )
    2212           0 :             aIt->Save( rStrm );
    2213           0 :         rStrm.EndRecord();
    2214             :     }
    2215           0 : }
    2216             : 
    2217           0 : sal_uInt16 XclExpLinkManagerImpl8::InsertXti( const XclExpXti& rXti )
    2218             : {
    2219           0 :     for( XclExpXtiVec::const_iterator aIt = maXtiVec.begin(), aEnd = maXtiVec.end(); aIt != aEnd; ++aIt )
    2220           0 :         if( *aIt == rXti )
    2221           0 :             return ulimit_cast< sal_uInt16 >( aIt - maXtiVec.begin() );
    2222           0 :     maXtiVec.push_back( rXti );
    2223           0 :     return ulimit_cast< sal_uInt16 >( maXtiVec.size() - 1 );
    2224             : }
    2225             : 
    2226           0 : XclExpLinkManager::XclExpLinkManager( const XclExpRoot& rRoot ) :
    2227           0 :     XclExpRoot( rRoot )
    2228             : {
    2229           0 :     switch( GetBiff() )
    2230             :     {
    2231             :         case EXC_BIFF5:
    2232           0 :             mxImpl.reset( new XclExpLinkManagerImpl5( rRoot ) );
    2233           0 :         break;
    2234             :         case EXC_BIFF8:
    2235           0 :             mxImpl.reset( new XclExpLinkManagerImpl8( rRoot ) );
    2236           0 :         break;
    2237             :         default:
    2238             :             DBG_ERROR_BIFF();
    2239             :     }
    2240           0 : }
    2241             : 
    2242           0 : XclExpLinkManager::~XclExpLinkManager()
    2243             : {
    2244           0 : }
    2245             : 
    2246           0 : void XclExpLinkManager::FindExtSheet(
    2247             :         sal_uInt16& rnExtSheet, sal_uInt16& rnXclTab,
    2248             :         SCTAB nScTab, XclExpRefLogEntry* pRefLogEntry )
    2249             : {
    2250           0 :     mxImpl->FindExtSheet( rnExtSheet, rnXclTab, rnXclTab, nScTab, nScTab, pRefLogEntry );
    2251           0 : }
    2252             : 
    2253           0 : void XclExpLinkManager::FindExtSheet(
    2254             :         sal_uInt16& rnExtSheet, sal_uInt16& rnFirstXclTab, sal_uInt16& rnLastXclTab,
    2255             :         SCTAB nFirstScTab, SCTAB nLastScTab, XclExpRefLogEntry* pRefLogEntry )
    2256             : {
    2257           0 :     mxImpl->FindExtSheet( rnExtSheet, rnFirstXclTab, rnLastXclTab, nFirstScTab, nLastScTab, pRefLogEntry );
    2258           0 : }
    2259             : 
    2260           0 : sal_uInt16 XclExpLinkManager::FindExtSheet( sal_Unicode cCode )
    2261             : {
    2262           0 :     return mxImpl->FindExtSheet( cCode );
    2263             : }
    2264             : 
    2265           0 : void XclExpLinkManager::FindExtSheet( sal_uInt16 nFileId, const OUString& rTabName, sal_uInt16 nXclTabSpan,
    2266             :                                       sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
    2267             :                                       XclExpRefLogEntry* pRefLogEntry )
    2268             : {
    2269           0 :     mxImpl->FindExtSheet( nFileId, rTabName, nXclTabSpan, rnExtSheet, rnFirstSBTab, rnLastSBTab, pRefLogEntry );
    2270           0 : }
    2271             : 
    2272           0 : void XclExpLinkManager::StoreCell( const ScSingleRefData& rRef, const ScAddress& rPos )
    2273             : {
    2274           0 :     mxImpl->StoreCellRange(rRef, rRef, rPos);
    2275           0 : }
    2276             : 
    2277           0 : void XclExpLinkManager::StoreCellRange( const ScComplexRefData& rRef, const ScAddress& rPos )
    2278             : {
    2279           0 :     mxImpl->StoreCellRange(rRef.Ref1, rRef.Ref2, rPos);
    2280           0 : }
    2281             : 
    2282           0 : void XclExpLinkManager::StoreCell( sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rPos )
    2283             : {
    2284           0 :     mxImpl->StoreCell(nFileId, rTabName, rPos);
    2285           0 : }
    2286             : 
    2287           0 : void XclExpLinkManager::StoreCellRange( sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange )
    2288             : {
    2289           0 :     mxImpl->StoreCellRange(nFileId, rTabName, rRange);
    2290           0 : }
    2291             : 
    2292           0 : bool XclExpLinkManager::InsertAddIn(
    2293             :         sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
    2294             : {
    2295           0 :     return mxImpl->InsertAddIn( rnExtSheet, rnExtName, rName );
    2296             : }
    2297             : 
    2298           0 : bool XclExpLinkManager::InsertEuroTool(
    2299             :         sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName )
    2300             : {
    2301           0 :     return mxImpl->InsertEuroTool( rnExtSheet, rnExtName, rName );
    2302             : }
    2303             : 
    2304           0 : bool XclExpLinkManager::InsertDde(
    2305             :         sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
    2306             :         const OUString& rApplic, const OUString& rTopic, const OUString& rItem )
    2307             : {
    2308           0 :     return mxImpl->InsertDde( rnExtSheet, rnExtName, rApplic, rTopic, rItem );
    2309             : }
    2310             : 
    2311           0 : bool XclExpLinkManager::InsertExtName(
    2312             :     sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const OUString& rName, const OUString& rUrl,
    2313             :     const ScExternalRefCache::TokenArrayRef pArray )
    2314             : {
    2315           0 :     return mxImpl->InsertExtName( rnExtSheet, rnExtName, rUrl, rName, pArray );
    2316             : }
    2317             : 
    2318           0 : void XclExpLinkManager::Save( XclExpStream& rStrm )
    2319             : {
    2320           0 :     mxImpl->Save( rStrm );
    2321           0 : }
    2322             : 
    2323             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10