ooo-build r13810 - in trunk: . patches/dev300



Author: kyoshida
Date: Fri Sep  5 15:12:39 2008
New Revision: 13810
URL: http://svn.gnome.org/viewvc/ooo-build?rev=13810&view=rev

Log:
2008-09-05  Kohei Yoshida  <kyoshida novell com>

	* patches/dev300/calc-external-defined-names-offapi.diff:
	* patches/dev300/calc-external-defined-names-sc.diff: updated with more
	changes both from myself and the upstream mooxlsc cws.


Modified:
   trunk/ChangeLog
   trunk/patches/dev300/calc-external-defined-names-offapi.diff
   trunk/patches/dev300/calc-external-defined-names-sc.diff

Modified: trunk/patches/dev300/calc-external-defined-names-offapi.diff
==============================================================================
--- trunk/patches/dev300/calc-external-defined-names-offapi.diff	(original)
+++ trunk/patches/dev300/calc-external-defined-names-offapi.diff	Fri Sep  5 15:12:39 2008
@@ -1,3 +1,17 @@
+diff --git offapi/com/sun/star/sheet/DatabaseRange.idl offapi/com/sun/star/sheet/DatabaseRange.idl
+index 4bbb5f5..6e66ba4 100644
+--- offapi/com/sun/star/sheet/DatabaseRange.idl
++++ offapi/com/sun/star/sheet/DatabaseRange.idl
+@@ -154,7 +154,8 @@ published service DatabaseRange
+     /** returns the index used to refer to this range in token arrays.
+ 
+         <p>A token describing a database range shall contain the op-code
+-        OPCODE_DB_AREA and this index as data part.</p>
++        obtained from the <const>FormulaMapGroupSpecialOffset::DB_AREA</const>
++        and this index as data part.</p>
+ 
+         @see com::sun::star::sheet::FormulaToken
+         @see com::sun::star::sheet::FormulaMapGroupSpecialOffset::DB_AREA
 diff --git offapi/com/sun/star/sheet/ExternalDocLink.idl offapi/com/sun/star/sheet/ExternalDocLink.idl
 new file mode 100644
 index 0000000..9c7f70d
@@ -284,10 +298,10 @@
 +
 diff --git offapi/com/sun/star/sheet/ExternalReference.idl offapi/com/sun/star/sheet/ExternalReference.idl
 new file mode 100644
-index 0000000..d1a5d00
+index 0000000..21f0e3a
 --- /dev/null
 +++ offapi/com/sun/star/sheet/ExternalReference.idl
-@@ -0,0 +1,92 @@
+@@ -0,0 +1,99 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -325,38 +339,40 @@
 +
 +//=============================================================================
 +
-+/** Data structure to store information about an external reference.  An 
++/** Data structure to store information about an external reference.  An
 +    external reference can be either a single cell reference, a cell range
 +    reference, or a named range.
 +
++    @see FormulaMapGroupSpecialOffset::EXTERNAL_REFERENCE
++
 +    @since OOo 3.1
 + */
 +struct ExternalReference
 +{
 +    //-------------------------------------------------------------------------
 +
-+    /** Index of an externally linked document.  Each externally-linked document 
++    /** Index of an externally linked document.  Each externally-linked document
 +        has a unique index value.
-+        
-+        <p>You can get the index value of an external document from the 
-+        corresponding <type scope="com::sun::star::sheet">ExternalDocLink</type> 
++
++        <p>You can get the index value of an external document from the
++        corresponding <type scope="com::sun::star::sheet">ExternalDocLink</type>
 +        instance through its attribute <type scope="com::sun::star::sheet::ExternalDocLink">TokenIndex</type>.</p>
 +
 +        @see com::sun::star::sheet::ExternalDocLink
 +        @see com::sun::star::sheet::ExternalDocLink::TokenIndex
 +     */
 +    long Index;
-+    
++
 +#if 0
 +    //-------------------------------------------------------------------------
 +
 +    /** Name of the sheet that the external reference points to.
 +
-+        <p>In case of a cell range reference that spans across multiple 
++        <p>In case of a cell range reference that spans across multiple
 +        sheets, this is the name of the first sheet in that range.</p>
 +
-+        <p>Note that an external range name ignores this value at the moment, 
-+        but <i>it may make use of this data in the future when Calc supports a 
++        <p>Note that an external range name ignores this value at the moment,
++        but <i>it may make use of this data in the future when Calc supports a
 +        sheet-specific range name.</i></p>
 +     */
 +    string SheetName;
@@ -364,10 +380,15 @@
 +
 +    //-------------------------------------------------------------------------
 +
-+    /** Reference data.  This can store either <type scope="com::sun::star::sheet">SingleReference</type>
-+        for a single cell reference, <type scope="com::sun::star::sheet">ComplexReference</type>
-+        for a cell range reference, or simply a <type>string</type> for a range 
-+        name.
++    /** Reference data.
++
++        <p>This can store either <type>SingleReference</type> for a single
++        cell reference, <type>ComplexReference</type> for a cell range
++        reference, or simply a <type>string</type> for a defined name.</p>
++
++        <p>The <member>SingleReference::Sheet</member> member shall contain
++        the index of the external sheet cache containing the values of the
++        externally referenced cells.</p>
 +
 +        @see com::sun::star::sheet::SingleReference
 +        @see com::sun::star::sheet::ComplexReference
@@ -441,25 +462,249 @@
 +}; }; }; };
 +
 +#endif
+diff --git offapi/com/sun/star/sheet/FormulaMapGroup.idl offapi/com/sun/star/sheet/FormulaMapGroup.idl
+index c128585..e846d72 100644
+--- offapi/com/sun/star/sheet/FormulaMapGroup.idl
++++ offapi/com/sun/star/sheet/FormulaMapGroup.idl
+@@ -47,7 +47,10 @@ module com {  module sun {  module star {  module sheet {
+  */
+ constants FormulaMapGroup
+ {
+-    /** Group of op-codes without a string symbol */
++    /** Group of op-codes without a string symbol.
++
++        @see FormulaMapGroupSpecialOffset
++      */
+     const long SPECIAL            = 0;
+ 
+     /** Separators and parentheses */
 diff --git offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl
-index 20369b2..6fa02d0 100644
+index 20369b2..7ebfe52 100644
 --- offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl
 +++ offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl
-@@ -59,6 +59,8 @@ constants FormulaMapGroupSpecialOffset
+@@ -31,37 +31,182 @@
+ #ifndef __com_sun_star_sheet_FormulaMapGroupSpecialOffset_idl__
+ #define __com_sun_star_sheet_FormulaMapGroupSpecialOffset_idl__
+ 
+-//=============================================================================
++// ===========================================================================
+ 
+ module com {  module sun {  module star {  module sheet {
+ 
+-//=============================================================================
++// ===========================================================================
+ 
+ /** Constants designating the offsets within the sequence returned by
+     <member>XFormurmulaOpCodeMapper::getAvailableMappings</member> when
+-    called for group <type>FormulaMapGroup</type> SPECIAL.
++    called for group <const>FormulaMapGroup::SPECIAL</const>.
+ 
+     The number of constants may grow in future versions!
+  */
+ constants FormulaMapGroupSpecialOffset
+ {
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        describe a formula operand token that will be pushed onto the formula
++        stack while the formula is interpreted.
++
++        <p>The <member>FormulaToken::Data</member> member shall contain one of
++        the following values:</p>
++
++        <ul>
++        <li>A value of type <atom>double</atom> for literal floating-point
++            constants.</li>
++        <li>A <atom>string</atom> for literal text.</li>
++        <li>A sequence of sequence of <atom>any</atom> for a literal array.
++            The contained values shall be of type <atom>double</atom> or
++            <atom>string</atom>. Floating-point values and strings may occur
++            together in an array.</li>
++        <li>A struct of type <type>SingleReference</type> for a reference to a
++            single cell in the own document.</li>
++        <li>A struct of type <type>ComplexReference</type> for a reference to
++            a range of cells in the own document.</li>
++        <li>A struct of type <type>ExternalReference</type> for a reference to
++            a cell, a range of cells, or a defined name in an external
++            document.</li>
++        </ul>
++     */
+     const long PUSH               = 0;
++
++    // -----------------------------------------------------------------------
++
+     const long CALL               = 1;
++
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        instruct the formula interpreter to immediately stop interpreting the
++        formula.
++
++        <p>The <member>FormulaToken::Data</member> member is not used
++        and should be empty.</p>
++     */
+     const long STOP               = 2;
++
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        describe the reference to an external function (e.g. add-in function)
++        used in formulas.
++
++        <p>The <member>FormulaToken::Data</member> member shall contain a
++        <atom>string</atom> with the programmatical name of the function, e.g.
++        "com.sun.star.sheet.addin.Analysis.getEomonth" for the EOMONTH
++        function from the Analsysis add-in.</p>
++     */
+     const long EXTERNAL           = 3;
++
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        describe the reference to a defined name (also known as named range)
++        used in formulas.
++
++        <p>The <member>FormulaToken::Data</member> member shall contain an
++        integer value of type <atom>long</atom> specifying the index of the
++        defined name. This index can be obtained from the defined name using
++        its <type>NamedRange::TokenIndex</type> property.</p>
++
++        @see  NamedRange
++     */
+     const long NAME               = 4;
++
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        describe an invalid name that resolves to the #NAME? error in formulas.
++
++        <p>The <member>FormulaToken::Data</member> member is not used
++        and should be empty.</p>
++     */
+     const long NO_NAME            = 5;
++
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        describe an empty function parameter.
++
++        <p>Example: In the formula =SUM(1;;2) the second parameter is empty
++        and represented by a formula token containing the "empty" op-code.</p>
++
++        <p>The <member>FormulaToken::Data</member> member is not used
++        and should be empty.</p>
++     */
+     const long MISSING            = 6;
++
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        describe "bad" data in a formula, e.g. data the formula parser was not
++        able to parse.
++
++        <p>The <member>FormulaToken::Data</member> member shall contain a
++        <atom>string</string> with the bad data. This string will be displayed
++        in the formula.</p>
++     */
+     const long BAD                = 7;
++
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        describe white-space characters within the string representation of a
++        formula.
++
++        <p>White-space characters in formulas are used for readability and do
++        not affect the result of the formula.</p>
++
++        <p>The <member>FormulaToken::Data</member> member shall contain a
++        positive integer value of type <atom>long</atom> specifying the number
++        of space characters.</p>
++
++        <p>Attention: This may change in next versions to support other
++        characters than simple space characters (e.g. line feeds, horizontal
++        tabulators, non-breakable spaces).</p>
++     */
+     const long SPACES             = 8;
++
++    // -----------------------------------------------------------------------
++
+     const long MAT_REF            = 9;
++
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        describe the reference to a database range used in formulas.
++
++        <p>The <member>FormulaToken::Data</member> member shall contain an
++        integer value of type <atom>long</atom> specifying the index of the
++        database range. This index can be obtained from the database range
++        using its <type>DatabaseRange::TokenIndex</type> property.</p>
++
++        @see  DatabaseRange
++     */
+     const long DB_AREA            = 10;
++
++    // -----------------------------------------------------------------------
++
++    /** Formula tokens containing the op-code obtained from this offset
++        describe the reference to a macro function called in a formula.
++
++        <p>The <member>FormulaToken::Data</member> member shall contain a
++        <atom>string</atom> specifying the name of the macro function.</p>
++     */
      const long MACRO              = 11;
++
++    // -----------------------------------------------------------------------
++
      const long COL_ROW_NAME       = 12;
-     const long COL_ROW_NAME_AUTO  = 13;
-+    /// @since OOo 3.1
-+    const long EXTERNAL_REFERENCE = 14;
+-    const long COL_ROW_NAME_AUTO  = 13;
++
++    // -----------------------------------------------------------------------
++
  };
  
- //=============================================================================
+-//=============================================================================
++// ===========================================================================
+ 
+ }; }; }; };
+ 
+diff --git offapi/com/sun/star/sheet/FormulaToken.idl offapi/com/sun/star/sheet/FormulaToken.idl
+index cec2ea4..c0aff64 100644
+--- offapi/com/sun/star/sheet/FormulaToken.idl
++++ offapi/com/sun/star/sheet/FormulaToken.idl
+@@ -44,6 +44,8 @@ struct FormulaToken
+     //-------------------------------------------------------------------------
+ 
+     /** is the OpCode of the token.
++
++        @see com::sun::star::sheet::XFormulaOpCodeMapper
+      */
+     long OpCode;
+ 
+diff --git offapi/com/sun/star/sheet/NamedRange.idl offapi/com/sun/star/sheet/NamedRange.idl
+index 30af011..c4d79dc 100644
+--- offapi/com/sun/star/sheet/NamedRange.idl
++++ offapi/com/sun/star/sheet/NamedRange.idl
+@@ -77,8 +77,9 @@ published service NamedRange
+ 
+     /** returns the index used to refer to this name in token arrays.
+ 
+-        <p>A token describing a defined name shall contain the op-code
+-        OPCODE_NAME and this index as data part.</p>
++        <p>A token describing a defined name shall contain the op-code obtained
++        from the <const>FormulaMapGroupSpecialOffset::NAME</const> offset and
++        this index as data part.</p>
+ 
+         @see com::sun::star::sheet::FormulaToken
+         @see com::sun::star::sheet::FormulaMapGroupSpecialOffset::NAME
 diff --git offapi/com/sun/star/sheet/XExternalDocLink.idl offapi/com/sun/star/sheet/XExternalDocLink.idl
 new file mode 100644
-index 0000000..0f3e02b
+index 0000000..e444682
 --- /dev/null
 +++ offapi/com/sun/star/sheet/XExternalDocLink.idl
-@@ -0,0 +1,84 @@
+@@ -0,0 +1,94 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -493,6 +738,9 @@
 +#ifndef __com_sun_star_sheet_XExternalDocLink_idl__
 +#define __com_sun_star_sheet_XExternalDocLink_idl__
 +
++#include <com/sun/star/container/XEnumerationAccess.idl>
++#include <com/sun/star/container/XIndexAccess.idl>
++#include <com/sun/star/container/XNameAccess.idl>
 +#include <com/sun/star/sheet/XExternalSheetCache.idl>
 +
 +module com {  module sun {  module star {  module sheet {
@@ -507,6 +755,10 @@
 + */
 +interface XExternalDocLink
 +{
++    interface com::sun::star::container::XNameAccess;
++    interface com::sun::star::container::XIndexAccess;
++    interface com::sun::star::container::XEnumerationAccess;
++
 +    //-------------------------------------------------------------------------
 +
 +    /** <p>This method adds a new sheet cache instance to the extternal document 
@@ -528,11 +780,14 @@
 +    
 +        <p>This index value corresponds with the external document 
 +        represented by an instance of 
-+        <type scope="com::sun::star::sheet">ExternalDocLink</type>.  This 
++        <type scope="com::sun::star::sheet">ExternalDocLink</type>.  This
 +        value is stored within a formula token instance.</p>
-+    
-+        <p>Each external document link has a unique index value.</p>
 +
++        <p>Each external document cache instance has a unique index value, and this
++        index value can be used to retrieve the corresponding external document cache
++        from the parent <type scope="com::sun::star::sheet">ExternalDocLinks</type> instance.</p>
++
++        @see com::sun::star::sheet::ExternalDocLinks
 +        @see com::sun::star::sheet::FormulaToken
 +        @see com::sun::star::sheet::FormulaMapGroupSpecialOffset::EXTERNAL_REFERENCE
 +     */
@@ -618,10 +873,10 @@
 +#endif
 diff --git offapi/com/sun/star/sheet/XExternalSheetCache.idl offapi/com/sun/star/sheet/XExternalSheetCache.idl
 new file mode 100644
-index 0000000..15655f8
+index 0000000..c246680
 --- /dev/null
 +++ offapi/com/sun/star/sheet/XExternalSheetCache.idl
-@@ -0,0 +1,84 @@
+@@ -0,0 +1,103 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -660,7 +915,7 @@
 +module com {  module sun {  module star {  module sheet {
 +
 +/** Primary interface for the <type scope="com::sun::star::sheet">ExternalSheetCache</type> service.
-+   
++
 +    @see com::sun::star::sheet::ExternalSheetCache
 +
 +    @since OOo 3.1.0
@@ -680,7 +935,7 @@
 +
 +    /** It retrieves a cached value from a specified cell position.  The cached
 +        value can be either <type>string</type> or <type>double</type>.
-+    
++
 +        @return any cached cell value
 +     */
 +    any getCellValue( [in] long nColumn, [in] long nRow )
@@ -693,14 +948,33 @@
 +     */
 +    sequence< long > getAllRows();
 +
-+    /** Given a row number, this method returns a list of all columns numbers 
-+        that store cached cell values in that row.  The column numbers are 
++    /** Given a row number, this method returns a list of all columns numbers
++        that store cached cell values in that row.  The column numbers are
 +        sorted in ascending order.
 +
 +        @return sequence<long> list of all columns numbers with cached cell values
 +     */
 +    sequence< long > getAllColumns( [in] long nRow )
 +            raises (com::sun::star::lang::IllegalArgumentException);
++
++    //-------------------------------------------------------------------------
++
++    /** Index corresponding to this instance of an external sheet cache for
++        usage in formula tokens.
++
++        <p>This index to the external sheet cache is expected in the
++        <member>SingleReference::Sheet</member> member if it is part of an
++        external reference token.
++
++        <p>Each external sheet cache has a unique index value inside the
++        <type>ExternalDocLink</type> instance.</p>
++
++        @see FormulaToken
++        @see ExternalReference
++        @see FormulaMapGroupSpecialOffset::EXTERNAL_REFERENCE
++     */
++    [attribute, readonly] long TokenIndex;
++
 +};
 +
 +}; }; }; };

Modified: trunk/patches/dev300/calc-external-defined-names-sc.diff
==============================================================================
--- trunk/patches/dev300/calc-external-defined-names-sc.diff	(original)
+++ trunk/patches/dev300/calc-external-defined-names-sc.diff	Fri Sep  5 15:12:39 2008
@@ -289,10 +289,10 @@
  
 diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
 new file mode 100644
-index 0000000..91be428
+index 0000000..90b8cd4
 --- /dev/null
 +++ sc/inc/externalrefmgr.hxx
-@@ -0,0 +1,405 @@
+@@ -0,0 +1,429 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -375,7 +375,7 @@
 +
 +// ============================================================================
 +
-+/** 
++/**
 + * Cache table for external reference data.
 + */
 +class ScExternalRefCache
@@ -391,20 +391,28 @@
 +    };
 +
 +public:
-+    
++
 +    typedef ::boost::shared_ptr<ScToken>            TokenRef;
 +    typedef ::boost::shared_ptr<ScTokenArray>       TokenArrayRef;
 +    typedef ::std::hash_map<SCCOL, TokenRef>        RowDataType;
 +    typedef ::std::hash_map<SCROW, RowDataType>     RowsDataType;
 +
++    struct TableName
++    {
++        String maUpperName;
++        String maRealName;
++
++        explicit TableName(const String& rUppper, const String& rReal);
++    };
++
 +    class Table
 +    {
 +    public:
 +        Table();
 +        ~Table();
 +
-+        void setCell(SCROW nRow, SCCOL nCol, TokenRef pToken);
-+        TokenRef getCell(SCROW nRow, SCCOL nCol) const;
++        void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken);
++        TokenRef getCell(SCCOL nCol, SCROW nRow) const;
 +        void getAllRows(::std::vector<SCROW>& rRows) const;
 +        void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols) const;
 +
@@ -421,24 +429,24 @@
 +    const String* getRealTableName(sal_uInt16 nFileId, const String& rTabName) const;
 +    const String* getRealRangeName(sal_uInt16 nFileId, const String& rRangeName) const;
 +
-+    /** 
++    /**
 +     * Get a cached cell data at specified cell location.
 +     *
 +     * @param nFileId file ID of an external document
 +     * @param rTabName sheet name
-+     * @param nRow 
-+     * @param nCol 
-+     * 
++     * @param nRow
++     * @param nCol
++     *
 +     * @return pointer to the token instance in the cache.  <i>The caller does
 +     *         not need to delete this instance since its life cycle is
 +     *         managed by this class.</i>
 +     */
 +    ScExternalRefCache::TokenRef getCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol);
 +
-+    /** 
-+     * Get a cached cell range data. 
-+     *  
-+     * @return a new token array instance.  Note that <i>the caller must 
++    /**
++     * Get a cached cell range data.
++     *
++     * @return a new token array instance.  Note that <i>the caller must
 +     *         manage the life cycle of the returned instance</i>, which is
 +     *         guaranteed if the TokenArrayRef is properly used..
 +     */
@@ -460,24 +468,13 @@
 +
 +    bool isDocInitialized(sal_uInt16 nFileId);
 +    void initializeDoc(sal_uInt16 nFileId, const ::std::vector<String>& rTabNames);
++    String getTableName(sal_uInt16 nFileId, size_t nCacheId) const;
 +    void getAllTableNames(sal_uInt16 nFileId, ::std::vector<String>& rTabNames) const;
++    bool hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const;
++    size_t getCacheTableCount(sal_uInt16 nFileId) const;
 +
-+    /** 
-+     * Get a cache table instance for specified file and table name.  If the 
-+     * table instance is not already present, it'll instantiate a new one and 
-+     * append it to the end of the table array.  <I>It's important to be 
-+     * aware of this fact especially for multi-table ranges for which 
-+     * table orders are critical.</I> 
-+     *  
-+     * Excel filter calls this method to populate the cache table from the 
-+     * XCT/CRN records. 
-+     *
-+     * @param nFileId file ID
-+     * @param rTabName table name
-+     * 
-+     * @return shared_ptr to the cache table instance
-+     */
-+    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew);
++    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
++    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex);
 +
 +    void clearCache(sal_uInt16 nFileId);
 +
@@ -486,14 +483,6 @@
 +    typedef ::std::hash_map<ScRange, TokenArrayRef, RangeHash>          RangeArrayMap;
 +    typedef ::std::hash_map<String, String, ScStringHashCode>           NamePairMap;
 +
-+    struct TableName
-+    {
-+        String maUpperName;
-+        String maRealName;
-+
-+        explicit TableName(const String& rUppper, const String& rReal);
-+    };
-+
 +    /** Represents data cached for a single external document. */
 +    struct DocItem
 +    {
@@ -565,35 +554,69 @@
 +    explicit ScExternalRefManager(ScDocument* pDoc);
 +    ~ScExternalRefManager();
 +
-+    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew = true);
++    String getCacheTableName(sal_uInt16 nFileId, size_t nTabIndex) const;
++
++    /**
++     * Get a cache table instance for specified table and table index.  Unlike
++     * the other method that takes a table name, this method does not create a
++     * new table when a table is not available for specified index.
++     *
++     * @param nFileId file ID
++     * @param nTabIndex cache table index
++     *
++     * @return shared_ptr to the cache table instance
++     */
++    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
++
++    /**
++     * Get a cache table instance for specified file and table name.  If the
++     * table instance is not already present, it'll instantiate a new one and
++     * append it to the end of the table array.  <I>It's important to be
++     * aware of this fact especially for multi-table ranges for which
++     * table orders are critical.</I>
++     *
++     * Excel filter calls this method to populate the cache table from the
++     * XCT/CRN records.
++     *
++     * @param nFileId file ID
++     * @param rTabName table name
++     *
++     * @return shared_ptr to the cache table instance
++     */
++    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex = 0);
++    void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector<String>& rTabNames) const;
++    bool hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const;
++    size_t getCacheTableCount(sal_uInt16 nFileId) const;
++    sal_uInt16 getExternalFileCount() const;
++
 +    void storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray);
 +
 +    ScExternalRefCache::TokenRef getSingleRefToken(sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell, const ScAddress* pCurPos, SCTAB* pTab);
 +
-+    /** 
-+     * Get an array of tokens that consist of the specified external cell 
-+     * range. 
++    /**
++     * Get an array of tokens that consist of the specified external cell
++     * range.
 +     *
 +     * @param nFileId file ID for an external document
 +     * @param rTabName referenced sheet name
 +     * @param rRange referenced cell range
-+     * @param pCurPos current cursor position to keep track of cells that 
++     * @param pCurPos current cursor position to keep track of cells that
 +     *                reference an external data.
-+     * 
-+     * @return shared_ptr to a token array instance.  <i>The caller must not 
++     *
++     * @return shared_ptr to a token array instance.  <i>The caller must not
 +     *         delete the instance returned by this method.</i>
 +     */
 +    ScExternalRefCache::TokenArrayRef getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
 +
-+    /** 
-+     * Get an array of tokens corresponding with a specified name in a 
-+     * specified file. 
-+     *  
-+     * @param pCurPos currnet cell address where this name token is used. 
++    /**
++     * Get an array of tokens corresponding with a specified name in a
++     * specified file.
++     *
++     * @param pCurPos currnet cell address where this name token is used.
 +     *                This is purely to keep track of all cells containing
 +     *                external names for refreshing purposes.  If this is
 +     *                NULL, then the cell will not be added to the list.
-+     * 
++     *
 +     * @return shared_ptr to array of tokens composing the name
 +     */
 +    ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos = NULL);
@@ -601,34 +624,33 @@
 +    const String& getOwnDocumentName() const;
 +    bool isOwnDocument(const String& rFile) const;
 +
-+    /** 
-+     * Takes a flat file name, and convert it to an absolute URL path.  An 
-+     * absolute URL path begines with 'file:///. 
++    /**
++     * Takes a flat file name, and convert it to an absolute URL path.  An
++     * absolute URL path begines with 'file:///.
 +     *
-+     * @param rFile file name to convert 
++     * @param rFile file name to convert
 +     */
 +    void convertToAbsName(String& rFile) const;
 +    sal_uInt16 getExternalFileId(const String& rFile);
 +    const String* getExternalFileName(sal_uInt16 nFileId) const;
++    bool hasExternalFile(sal_uInt16 nFileId) const;
++    bool hasExternalFile(const String& rFile) const;
 +    const SrcFileData* getExternalFileData(sal_uInt16 nFileId) const;
 +
 +    const String* getRealTableName(sal_uInt16 nFileId, const String& rTabName) const;
 +    const String* getRealRangeName(sal_uInt16 nFileId, const String& rRangeName) const;
-+    void getAllCachedTableNames(sal_uInt16 nFileId, ::std::vector<String>& rTabNames) const;
-+    sal_uInt16 getCachedFileCount() const;
 +    void refreshNames(sal_uInt16 nFileId);
 +    void switchSrcFile(sal_uInt16 nFileId, const String& rNewFile);
 +
 +    void setRelativeFileName(sal_uInt16 nFileId, const String& rRelUrl);
 +
-+    /** 
-+     * Set the filter name and options if any for a given source document. 
-+     * These values get reset when the source document ever gets reloaded. 
++    /**
++     * Set the filter name and options if any for a given source document.
++     * These values get reset when the source document ever gets reloaded.
 +     *
-+     * @param nFileId 
-+     * @param rFilterName 
-+     * @param rOptions 
-+     * @return 
++     * @param nFileId
++     * @param rFilterName
++     * @param rOptions
 +     */
 +    void setFilterData(sal_uInt16 nFileId, const String& rFilterName, const String& rOptions);
 +
@@ -637,20 +659,22 @@
 +
 +    bool hasExternalData() const;
 +
-+    /** 
-+     * Re-generates relative names for all stored source files.  This is 
-+     * necessary when exporting to an ods document, to ensure that all source 
++    /**
++     * Re-generates relative names for all stored source files.  This is
++     * necessary when exporting to an ods document, to ensure that all source
 +     * files have their respective relative names for xlink:href export.
 +     */
 +    void resetSrcFileData();
 +
++    void updateRefCell(const ScAddress& rOldPos, const ScAddress& rNewPos);
++
 +private:
 +    ScExternalRefManager();
-+    ScExternalRefManager(const ScExternalRefManager&); 
++    ScExternalRefManager(const ScExternalRefManager&);
 +
-+    void refreshAllReferencingCells(sal_uInt16 nFileId);
++    void refreshAllRefCells(sal_uInt16 nFileId);
 +
-+    void insertReferencingCell(sal_uInt16 nFileId, const ScAddress& rCell);
++    void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
 +
 +    ScDocument* getSrcDocument(sal_uInt16 nFileId);
 +    SfxObjectShellRef loadSrcDocument(sal_uInt16 nFileId, String& rFilter);
@@ -660,11 +684,11 @@
 +
 +    bool compileTokensByCell(const ScAddress& rCell);
 +
-+    /** 
-+     * Purge those source document instances that have not been accessed for 
++    /**
++     * Purge those source document instances that have not been accessed for
 +     * the specified duration.
-+     *  
-+     * @param nTimeOut time out value in 100th of a second 
++     *
++     * @param nTimeOut time out value in 100th of a second
 +     */
 +    void purgeStaleSrcDocument(sal_Int32 nTimeOut);
 +
@@ -674,8 +698,8 @@
 +
 +    ScDocument* mpDoc;
 +
-+    /** 
-+     * Source document cache.  This stores the original source document shell 
++    /**
++     * Source document cache.  This stores the original source document shell
 +     * instances.  They get purged after a certain period of time.
 +     */
 +    DocShellMap maDocShells;
@@ -683,7 +707,7 @@
 +    /** list of source documents that are managed by the link manager. */
 +    LinkedDocSet maLinkedDocs;
 +
-+    /** 
++    /**
 +     * List of referencing cells that may contain external names.  There is
 +     * one list per source document.
 +     */
@@ -699,7 +723,7 @@
 +
 +#endif
 diff --git sc/inc/linkuno.hxx sc/inc/linkuno.hxx
-index b6fc524..f5af67d 100644
+index b6fc524..0a12196 100644
 --- sc/inc/linkuno.hxx
 +++ sc/inc/linkuno.hxx
 @@ -36,6 +36,9 @@
@@ -728,7 +752,7 @@
  
  class ScAreaLink;
  class ScDocShell;
-@@ -493,8 +501,112 @@ public:
+@@ -493,8 +501,137 @@ public:
  								throw(::com::sun::star::uno::RuntimeException);
  };
  
@@ -737,7 +761,7 @@
 +class ScExternalSheetCacheObj : public cppu::WeakImplHelper1< ::com::sun::star::sheet::XExternalSheetCache >
 +{
 +public:
-+    explicit ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable);
++    explicit ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable, size_t nIndex);
 +    ~ScExternalSheetCacheObj();
 +
 +                            // XExternalSheetCache
@@ -754,12 +778,17 @@
 +    virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL getAllColumns(sal_Int32 nRow)
 +        throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
 +
++    // Attributes
++    virtual sal_Int32 SAL_CALL getTokenIndex()
++            throw (::com::sun::star::uno::RuntimeException);
++
 +private:
 +    ScExternalSheetCacheObj();
 +    ScExternalSheetCacheObj(const ScExternalSheetCacheObj&);
 +
 +private:
 +    ScExternalRefCache::TableTypeRef mpTable;
++    size_t mnIndex;
 +};
 +
 +// ============================================================================
@@ -771,10 +800,36 @@
 +    ~ScExternalDocLinkObj();
 +
 +                            // XExternalDocLink
-+    virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache > 
-+        SAL_CALL addSheetCache( const ::rtl::OUString& aSheetName ) 
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache >
++        SAL_CALL addSheetCache( const ::rtl::OUString& aSheetName )
 +            throw (::com::sun::star::uno::RuntimeException);
 +
++							// XNameAccess
++	virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
++								throw(::com::sun::star::container::NoSuchElementException,
++									::com::sun::star::lang::WrappedTargetException,
++									::com::sun::star::uno::RuntimeException);
++	virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
++								throw(::com::sun::star::uno::RuntimeException);
++	virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
++								throw(::com::sun::star::uno::RuntimeException);
++
++							// XIndexAccess
++	virtual sal_Int32 SAL_CALL getCount() throw(::com::sun::star::uno::RuntimeException);
++	virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( sal_Int32 nIndex )
++								throw(::com::sun::star::lang::IndexOutOfBoundsException,
++									::com::sun::star::lang::WrappedTargetException,
++									::com::sun::star::uno::RuntimeException);
++
++							// XEnumerationAccess
++	virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL
++							createEnumeration() throw(::com::sun::star::uno::RuntimeException);
++
++							// XElementAccess
++	virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
++								throw(::com::sun::star::uno::RuntimeException);
++	virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
++
 +    // Attributes
 +    virtual sal_Int32 SAL_CALL getTokenIndex()
 +            throw (::com::sun::star::uno::RuntimeException);
@@ -785,19 +840,19 @@
 +};
 +
 +// ============================================================================
-+
+ 
 +/** This is the UNO API equivalent of ScExternalRefManager. */
 +class ScExternalDocLinksObj : public cppu::WeakImplHelper1< ::com::sun::star::sheet::XExternalDocLinks >
 +{
 +public:
 +    ScExternalDocLinksObj(ScDocShell* pDocShell);
 +    ~ScExternalDocLinksObj();
-+
+ 
 +                            // XExternalDocLinks
-+    virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalDocLink > 
-+        SAL_CALL addDocLink( const ::rtl::OUString& aDocName ) 
++    virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalDocLink >
++        SAL_CALL addDocLink( const ::rtl::OUString& aDocName )
 +            throw (::com::sun::star::uno::RuntimeException);
- 
++
 +							// XNameAccess
 +	virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
 +								throw(::com::sun::star::container::NoSuchElementException,
@@ -823,18 +878,12 @@
 +	virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
 +								throw(::com::sun::star::uno::RuntimeException);
 +	virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
- 
++
 +private:
 +    ScExternalDocLinksObj();
 +    ScExternalDocLinksObj(const ScExternalDocLinksObj&);
 +
 +private:
-+    typedef ::std::hash_map< 
-+        ::rtl::OUString, 
-+        ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalDocLink >, 
-+        ::rtl::OUStringHash > DocLinkMap;
-+    DocLinkMap                          maDocLinks;
-+    ::std::vector< ::rtl::OUString >    maDocNames;
 +    ScDocShell*                         mpDocShell;
 +    ScExternalRefManager*               mpRefMgr;
 +};
@@ -965,7 +1014,7 @@
      /** Xcl import may play dirty tricks with OpCode!=ocExternal.
          Others don't use! */
 diff --git sc/inc/tokenuno.hxx sc/inc/tokenuno.hxx
-index a03b6ec..5db0e32 100644
+index a03b6ec..f12b484 100644
 --- sc/inc/tokenuno.hxx
 +++ sc/inc/tokenuno.hxx
 @@ -38,9 +38,8 @@
@@ -979,7 +1028,19 @@
  #include <cppuhelper/implbase3.hxx>
  #include <cppuhelper/implbase2.hxx>
  #include "address.hxx"
-@@ -70,6 +69,7 @@ class ScFormulaParserObj : public ::cppu::WeakImplHelper3<
+@@ -54,9 +53,11 @@ class ScTokenConversion
+ {
+ public:
+     static bool ConvertToTokenArray(
++                        ScDocument& rDoc,
+                         ScTokenArray& rTokenArray,
+                         const com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& rSequence );
+     static bool ConvertToTokenSequence(
++                        ScDocument& rDoc,
+                         com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& rSequence,
+                         const ScTokenArray& rTokenArray );
+ };
+@@ -70,6 +71,7 @@ class ScFormulaParserObj : public ::cppu::WeakImplHelper3<
  {
  private:
      ::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::FormulaOpCodeMapEntry > maOpCodeMapping;
@@ -1025,6 +1086,45 @@
  			{
  				ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( t->GetIndex() );
  				if( pRangeData )
+diff --git sc/source/core/data/cell2.cxx sc/source/core/data/cell2.cxx
+index fc6df5f..2d71b6e 100644
+--- sc/source/core/data/cell2.cxx
++++ sc/source/core/data/cell2.cxx
+@@ -7,7 +7,7 @@
+  * OpenOffice.org - a multi-platform office productivity suite
+  *
+  * $RCSfile: cell2.cxx,v $
+- * $Revision: 1.34 $
++ * $Revision: 1.34.108.4 $
+  *
+  * This file is part of OpenOffice.org.
+  *
+@@ -51,6 +51,7 @@
+ #include "indexmap.hxx"
+ #include "scitems.hxx"
+ #include "patattr.hxx"
++#include "externalrefmgr.hxx"
+ 
+ // STATIC DATA -----------------------------------------------------------
+ 
+@@ -904,6 +905,17 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
+ 
+         delete pOld;
+     }
++
++    pCode->Reset();
++    for ( ScToken* t = pCode->GetNextReferenceOrName(); t; t = pCode->GetNextReferenceOrName() )
++    {
++        StackVar sv = t->GetType();
++        if (sv == svExternalSingleRef || sv == svExternalDoubleRef || sv == svExternalName)
++        {
++            pDocument->GetExternalRefManager()->updateRefCell(aOldPos, aPos);    
++            break;
++        }
++    }
+ }
+ 
+ void ScFormulaCell::UpdateInsertTab(SCTAB nTable)
 diff --git sc/source/core/data/documen2.cxx sc/source/core/data/documen2.cxx
 index b75279e..d739a17 100644
 --- sc/source/core/data/documen2.cxx
@@ -1141,6 +1241,40 @@
  void ScDocument::UpdateDdeLinks()
  {
      if (pLinkManager)
+diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
+index 886156d..0fb382f 100644
+--- sc/source/core/data/document.cxx
++++ sc/source/core/data/document.cxx
+@@ -7,7 +7,7 @@
+  * OpenOffice.org - a multi-platform office productivity suite
+  *
+  * $RCSfile: document.cxx,v $
+- * $Revision: 1.90 $
++ * $Revision: 1.90.44.2 $
+  *
+  * This file is part of OpenOffice.org.
+  *
+diff --git sc/source/core/inc/interpre.hxx sc/source/core/inc/interpre.hxx
+index b9dd766..3a85852 100644
+--- sc/source/core/inc/interpre.hxx
++++ sc/source/core/inc/interpre.hxx
+@@ -7,7 +7,7 @@
+  * OpenOffice.org - a multi-platform office productivity suite
+  *
+  * $RCSfile: interpre.hxx,v $
+- * $Revision: 1.35 $
++ * $Revision: 1.35.44.1 $
+  *
+  * This file is part of OpenOffice.org.
+  *
+@@ -505,6 +505,7 @@ BOOL SetSbxVariable( SbxVariable* pVar, SCCOL nCol, SCROW nRow, SCTAB nTab );
+ void ScErrorType();
+ void ScDBArea();
+ void ScColRowNameAuto();
++void ScExternalRef();
+ void ScGetPivotData();
+ void ScHyperLink();
+ void ScBahtText();
 diff --git sc/source/core/tool/address.cxx sc/source/core/tool/address.cxx
 index 2cb5dce..44c84c0 100644
 --- sc/source/core/tool/address.cxx
@@ -1965,7 +2099,7 @@
          aString.Append( '$' );
  
 diff --git sc/source/core/tool/compiler.cxx sc/source/core/tool/compiler.cxx
-index 918332d..0910e72 100644
+index 918332d..41df88b 100644
 --- sc/source/core/tool/compiler.cxx
 +++ sc/source/core/tool/compiler.cxx
 @@ -74,9 +74,11 @@
@@ -2017,15 +2151,15 @@
  }
  
  // static
-@@ -737,10 +734,28 @@ void ScCompiler::SetFormulaLanguage( const ScCompiler::OpCodeMapPtr & xMap )
+@@ -737,7 +734,25 @@ void ScCompiler::SetFormulaLanguage( const ScCompiler::OpCodeMapPtr & xMap )
          }
          else
              pCharClass = ScGlobal::pCharClass;
 +        SetGrammarAndRefConvention( mxSymbols->getGrammar(), GetGrammar());
-     }
- }
- 
- 
++    }
++}
++
++
 +void ScCompiler::SetGrammarAndRefConvention(
 +        const ScGrammar::Grammar eNewGrammar, const ScGrammar::Grammar eOldGrammar )
 +{
@@ -2037,16 +2171,13 @@
 +            SetRefConvention( pDoc->GetAddressConvention());
 +        else
 +            SetRefConvention( pConvOOO_A1);
-+    }
+     }
 +    else
 +        SetRefConvention( eConv );
-+}
-+
-+
- //-----------------------------------------------------------------------------
+ }
+ 
  
- void ScCompiler::OpCodeMap::putOpCode( const String & rStr, const OpCode eOp )
-@@ -866,20 +881,21 @@ ScCompiler::OpCodeMap::createSequenceOfAvailableMappings( const sal_Int32 nGroup
+@@ -866,20 +881,19 @@ ScCompiler::OpCodeMap::createSequenceOfAvailableMappings( const sal_Int32 nGroup
              sal_Int32 nOff;
              OpCode    eOp;
          } aMap[] = {
@@ -2064,25 +2195,23 @@
 -            { FormulaMapGroupSpecialOffset::MACRO             , ocMacro }          ,
 -            { FormulaMapGroupSpecialOffset::COL_ROW_NAME      , ocColRowName }     ,
 -            { FormulaMapGroupSpecialOffset::COL_ROW_NAME_AUTO , ocColRowNameAuto }
-+            { FormulaMapGroupSpecialOffset::PUSH               , ocPush }           , 
-+            { FormulaMapGroupSpecialOffset::CALL               , ocCall }           , 
-+            { FormulaMapGroupSpecialOffset::STOP               , ocStop }           , 
-+            { FormulaMapGroupSpecialOffset::EXTERNAL           , ocExternal }       , 
-+            { FormulaMapGroupSpecialOffset::NAME               , ocName }           , 
-+            { FormulaMapGroupSpecialOffset::NO_NAME            , ocNoName }         , 
-+            { FormulaMapGroupSpecialOffset::MISSING            , ocMissing }        , 
-+            { FormulaMapGroupSpecialOffset::BAD                , ocBad }            , 
-+            { FormulaMapGroupSpecialOffset::SPACES             , ocSpaces }         , 
-+            { FormulaMapGroupSpecialOffset::MAT_REF            , ocMatRef }         , 
-+            { FormulaMapGroupSpecialOffset::DB_AREA            , ocDBArea }         , 
-+            { FormulaMapGroupSpecialOffset::MACRO              , ocMacro }          , 
-+            { FormulaMapGroupSpecialOffset::COL_ROW_NAME       , ocColRowName }     , 
-+            { FormulaMapGroupSpecialOffset::COL_ROW_NAME_AUTO  , ocColRowNameAuto } , 
-+            { FormulaMapGroupSpecialOffset::EXTERNAL_REFERENCE , ocExternalRef }
++            { FormulaMapGroupSpecialOffset::PUSH               , ocPush }           ,
++            { FormulaMapGroupSpecialOffset::CALL               , ocCall }           ,
++            { FormulaMapGroupSpecialOffset::STOP               , ocStop }           ,
++            { FormulaMapGroupSpecialOffset::EXTERNAL           , ocExternal }       ,
++            { FormulaMapGroupSpecialOffset::NAME               , ocName }           ,
++            { FormulaMapGroupSpecialOffset::NO_NAME            , ocNoName }         ,
++            { FormulaMapGroupSpecialOffset::MISSING            , ocMissing }        ,
++            { FormulaMapGroupSpecialOffset::BAD                , ocBad }            ,
++            { FormulaMapGroupSpecialOffset::SPACES             , ocSpaces }         ,
++            { FormulaMapGroupSpecialOffset::MAT_REF            , ocMatRef }         ,
++            { FormulaMapGroupSpecialOffset::DB_AREA            , ocDBArea }         ,
++            { FormulaMapGroupSpecialOffset::MACRO              , ocMacro }          ,
++            { FormulaMapGroupSpecialOffset::COL_ROW_NAME       , ocColRowName }
          };
          const size_t nCount = sizeof(aMap)/sizeof(aMap[0]);
          // Preallocate vector elements.
-@@ -1078,7 +1094,7 @@ ScCompiler::Convention::Convention( ScAddress::Convention eConv )
+@@ -1078,7 +1092,7 @@ ScCompiler::Convention::Convention( ScAddress::Convention eConv )
  /*   */     t[32] = SC_COMPILER_C_CHAR_DONTCARE | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
  /* ! */     t[33] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
      if (ScAddress::CONV_ODF == meConv)
@@ -2091,7 +2220,7 @@
  /* " */     t[34] = SC_COMPILER_C_CHAR_STRING | SC_COMPILER_C_STRING_SEP;
  /* # */     t[35] = SC_COMPILER_C_WORD_SEP;
  /* $ */     t[36] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
-@@ -1093,8 +1109,10 @@ ScCompiler::Convention::Convention( ScAddress::Convention eConv )
+@@ -1093,8 +1107,10 @@ ScCompiler::Convention::Convention( ScAddress::Convention eConv )
  /* - */     t[45] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN;
  /* . */     t[46] = SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE | SC_COMPILER_C_IDENT;
  /* / */     t[47] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
@@ -2103,7 +2232,7 @@
  /* : */     t[58] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD;
  /* ; */     t[59] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
  /* < */     t[60] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-@@ -1102,8 +1120,10 @@ for (i = 48; i < 58; i++)
+@@ -1102,8 +1118,10 @@ for (i = 48; i < 58; i++)
  /* > */     t[62] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
  /* ? */     t[63] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD;
  /* @ */     // FREE
@@ -2115,7 +2244,7 @@
      if (ScAddress::CONV_ODF == meConv)
      {
  /* [ */     t[91] = SC_COMPILER_C_ODF_LBRACKET;
-@@ -1119,14 +1139,17 @@ for (i = 65; i < 91; i++)
+@@ -1119,14 +1137,17 @@ for (i = 65; i < 91; i++)
  /* ^ */     t[94] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
  /* _ */     t[95] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
  /* ` */     // FREE
@@ -2135,7 +2264,7 @@
      {
  /*   */     t[32] |=   SC_COMPILER_C_WORD;
  /* ! */     t[33] |=   SC_COMPILER_C_IDENT | SC_COMPILER_C_WORD;
-@@ -1165,9 +1188,14 @@ for (i = 97; i < 123; i++)
+@@ -1165,9 +1186,14 @@ for (i = 97; i < 123; i++)
  
          if( ScAddress::CONV_XL_R1C1 == meConv )
          {
@@ -2153,7 +2282,7 @@
          }
      }
  }
-@@ -1191,7 +1219,7 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
+@@ -1191,7 +1217,7 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
                  {
                      rRes.TokenType = KParseType::SINGLE_QUOTE_NAME;
                      rRes.EndPos = nPos+1;
@@ -2162,7 +2291,7 @@
                  }
                  ++nPos;
              }
-@@ -1199,9 +1227,203 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
+@@ -1199,9 +1225,203 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
          }
      }
  
@@ -2196,7 +2325,7 @@
 +                    if (c == '\'')
 +                    {
 +                        if (j == i)
-+                        {    
++                        {
 +                            // empty quote e.g. (=''!Name)
 +                            return false;
 +                        }
@@ -2229,13 +2358,13 @@
 +                }
 +
 +                if (!bInName)
-+                {    
++                {
 +                    // premature ending of the quoted segment.
 +                    return false;
 +                }
 +
 +                if (c != cSep)
-+                {    
++                {
 +                    // only the separator is allowed after the closing quote.
 +                    return false;
 +                }
@@ -2302,9 +2431,9 @@
 +
 +    rFile = aTmpFile;
 +    rName = aTmpName;
-+    return true;
-+}
-+
+     return true;
+ }
+ 
 +static String lcl_makeExternalNameStr( const String& rFile, const String& rName,
 +        const sal_Unicode cSep, bool bODF )
 +{
@@ -2323,7 +2452,7 @@
 +    return String( aBuf.makeStringAndClear());
 +}
 +
-+static bool lcl_getLastTabName( String& rTabName2, const String& rTabName1, 
++static bool lcl_getLastTabName( String& rTabName2, const String& rTabName1,
 +                                const vector<String>& rTabNames, const ComplRefData& rRef )
 +{
 +    SCsTAB nTabSpan = rRef.Ref2.nTab - rRef.Ref1.nTab;
@@ -2335,7 +2464,7 @@
 +        if (itr == rTabNames.end())
 +        {
 +            rTabName2 = ScGlobal::GetRscString(STR_NO_REF_TABLE);
-+            return false;    
++            return false;
 +        }
 +
 +        size_t nDist = ::std::distance(itrBeg, itr);
@@ -2350,9 +2479,9 @@
 +    else
 +        rTabName2 = rTabName1;
 +
-     return true;
- }
- 
++    return true;
++}
++
 +static void lcl_appendTabName(::rtl::OUStringBuffer& rBuffer, const String& rTabName)
 +{
 +    bool bQuote = (rTabName.Search(sal_Unicode(' '), 0) != STRING_NOTFOUND);
@@ -2366,7 +2495,7 @@
  struct Convention_A1 : public ScCompiler::Convention
  {
      Convention_A1( ScAddress::Convention eConv ) : ScCompiler::Convention( eConv ) { }
-@@ -1215,14 +1437,14 @@ struct Convention_A1 : public ScCompiler::Convention
+@@ -1215,14 +1435,14 @@ struct Convention_A1 : public ScCompiler::Convention
                                 const CharClass* pCharClass) const
      {
          ParseResult aRet;
@@ -2383,7 +2512,7 @@
          return pCharClass->parseAnyToken( rFormula,
                  nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
      }
-@@ -1405,6 +1627,114 @@ struct ConventionOOO_A1 : public Convention_A1
+@@ -1405,6 +1625,114 @@ struct ConventionOOO_A1 : public Convention_A1
  
          return sal_Unicode(0);
      }
@@ -2398,8 +2527,8 @@
 +        return lcl_makeExternalNameStr( rFile, rName, sal_Unicode('#'), false);
 +    }
 +
-+    bool makeExternalSingleRefStr( ::rtl::OUStringBuffer& rBuffer, sal_uInt16 nFileId, 
-+                                   const String& rTabName, const SingleRefData& rRef, 
++    bool makeExternalSingleRefStr( ::rtl::OUStringBuffer& rBuffer, sal_uInt16 nFileId,
++                                   const String& rTabName, const SingleRefData& rRef,
 +                                   ScExternalRefManager* pRefMgr, bool bDisplayTabName ) const
 +    {
 +        if (bDisplayTabName)
@@ -2409,12 +2538,12 @@
 +            if (p)
 +                aFile = *p;
 +            aFile.SearchAndReplaceAllAscii("'", String::CreateFromAscii("''"));
-+    
++
 +            rBuffer.append(sal_Unicode('\''));
 +            rBuffer.append(aFile);
 +            rBuffer.append(sal_Unicode('\''));
 +            rBuffer.append(sal_Unicode('#'));
-+    
++
 +            // external reference is always 3D and the sheet is absolute.
 +            rBuffer.append(sal_Unicode('$'));
 +            lcl_appendTabName(rBuffer, rTabName);
@@ -2433,7 +2562,7 @@
 +    }
 +
 +    void makeExternalRefStrImpl( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr, bool bODF ) const
 +    {
 +        SingleRefData aRef(rRef);
@@ -2447,14 +2576,14 @@
 +    }
 +
 +    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr ) const
 +    {
 +        makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, false);
 +    }
 +
 +    void makeExternalRefStrImpl( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr, bool bODF ) const
 +    {
 +        ComplRefData aRef(rRef);
@@ -2490,7 +2619,7 @@
 +    }
 +
 +    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr ) const
 +    {
 +        makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, false);
@@ -2498,7 +2627,7 @@
  };
  
  
-@@ -1423,6 +1753,25 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1
+@@ -1423,6 +1751,25 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1
      {
          MakeRefStrImpl( rBuffer, rComp, rRef, bSingleRef, true);
      }
@@ -2509,14 +2638,14 @@
 +    }
 +
 +    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr ) const
 +    {
 +        makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, true);
 +    }
 +
 +    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr ) const
 +    {
 +        makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, true);
@@ -2524,7 +2653,7 @@
  };
  
  static const ConventionOOO_A1_ODF ConvOOO_A1_ODF;
-@@ -1526,11 +1875,129 @@ struct ConventionXL
+@@ -1526,11 +1873,129 @@ struct ConventionXL
          }
          return sal_Unicode(0);
      }
@@ -2541,11 +2670,11 @@
 +
 +    static void makeExternalDocStr( ::rtl::OUStringBuffer& rBuffer, const String& rFullName )
 +    {
-+        // Format that is easier to deal with inside OOo, because we use file 
++        // Format that is easier to deal with inside OOo, because we use file
 +        // URL, and all characetrs are allowed.  Check if it makes sense to do
 +        // it the way Gnumeric does it.  Gnumeric doesn't use the URL form
 +        // and allows relative file path.
-+        // 
++        //
 +        //   ['file:///path/to/source/filename.xls']
 +
 +        rBuffer.append(sal_Unicode('['));
@@ -2563,14 +2692,14 @@
 +        rBuffer.append(sal_Unicode(']'));
 +    }
 +
-+    static void makeExternalTabNameRange( ::rtl::OUStringBuffer& rBuf, const String& rTabName, 
++    static void makeExternalTabNameRange( ::rtl::OUStringBuffer& rBuf, const String& rTabName,
 +                                          const vector<String>& rTabNames,
 +                                          const ComplRefData& rRef )
 +    {
 +        String aLastTabName;
 +        if (!lcl_getLastTabName(aLastTabName, rTabName, rTabNames, rRef))
 +        {
-+            rBuf.append(aLastTabName);   
++            rBuf.append(aLastTabName);
 +            return;
 +        }
 +
@@ -2605,7 +2734,7 @@
 +            else if (c == '\'')
 +            {
 +                if (cPrev == '\'')
-+                    // two successive single quote is treated as a single 
++                    // two successive single quote is treated as a single
 +                    // valid character.
 +                    c = 'a';
 +            }
@@ -2627,7 +2756,7 @@
 +            {
 +                // any other character
 +                if (i > rSrcPos + 2 && cPrev == '\'')
-+                    // unless it's the 3rd character, a normal character 
++                    // unless it's the 3rd character, a normal character
 +                    // following immediately a single quote is invalid.
 +                    return;
 +            }
@@ -2654,7 +2783,7 @@
      void MakeRefStr( rtl::OUStringBuffer&   rBuf,
                       const ScCompiler&      rComp,
                       const ComplRefData& rRef,
-@@ -1584,22 +2051,11 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1584,22 +2049,11 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
              }
          }
  
@@ -2679,7 +2808,7 @@
          }
      }
  
-@@ -1607,8 +2063,10 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1607,8 +2061,10 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
                                         xub_StrLen nSrcPos,
                                         const CharClass* pCharClass) const
      {
@@ -2691,7 +2820,7 @@
              return aRet;
  
          static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
-@@ -1624,11 +2082,83 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1624,11 +2080,83 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
      {
          return ConventionXL::getSpecialSymbol(eSymType);
      }
@@ -2707,13 +2836,13 @@
 +    }
 +
 +    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr ) const
 +    {
 +        // ['file:///path/to/file/filename.xls']'Sheet Name'!$A$1
 +        // This is a little different from the format Excel uses, as Excel
 +        // puts [] only around the file name.  But we need to enclose the
-+        // whole file path with [] because the file name can contain any 
++        // whole file path with [] because the file name can contain any
 +        // characters.
 +
 +        const String* pFullName = pRefMgr->getExternalFileName(nFileId);
@@ -2731,7 +2860,7 @@
 +    }
 +
 +    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr ) const
 +    {
 +        const String* pFullName = pRefMgr->getExternalFileName(nFileId);
@@ -2775,7 +2904,7 @@
  //-----------------------------------------------------------------------------
  
  static void
-@@ -1733,8 +2263,10 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
+@@ -1733,8 +2261,10 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
                                 xub_StrLen nSrcPos,
                                 const CharClass* pCharClass) const
      {
@@ -2787,7 +2916,7 @@
              return aRet;
  
          static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
-@@ -1751,6 +2283,96 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
+@@ -1751,6 +2281,96 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
      {
          return ConventionXL::getSpecialSymbol(eSymType);
      }
@@ -2803,13 +2932,13 @@
 +    }
 +
 +    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr ) const
 +    {
 +        // ['file:///path/to/file/filename.xls']'Sheet Name'!$A$1
 +        // This is a little different from the format Excel uses, as Excel
 +        // puts [] only around the file name.  But we need to enclose the
-+        // whole file path with [] because the file name can contain any 
++        // whole file path with [] because the file name can contain any
 +        // characters.
 +
 +        const String* pFullName = pRefMgr->getExternalFileName(nFileId);
@@ -2828,7 +2957,7 @@
 +    }
 +
 +    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
-+                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef, 
++                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef,
 +                                     ScExternalRefManager* pRefMgr ) const
 +    {
 +        const String* pFullName = pRefMgr->getExternalFileName(nFileId);
@@ -2884,7 +3013,7 @@
  };
  
  static const ConventionXL_R1C1 ConvXL_R1C1;
-@@ -1817,13 +2439,15 @@ void ScCompiler::CheckTabQuotes( String& rString,
+@@ -1817,13 +2437,15 @@ void ScCompiler::CheckTabQuotes( String& rString,
          KParseType::IDENTNAME, rString, 0, nStartFlags, EMPTY_STRING, nContFlags, EMPTY_STRING);
      bool bNeedsQuote = !((aRes.TokenType & KParseType::IDENTNAME) && aRes.EndPos == rString.Len());
  
@@ -2901,7 +3030,7 @@
              if( bNeedsQuote )
              {
                  static const String one_quote = static_cast<sal_Unicode>( '\'' );
-@@ -1859,6 +2483,7 @@ void ScCompiler::SetRefConvention( ScAddress::Convention eConv )
+@@ -1859,6 +2481,7 @@ void ScCompiler::SetRefConvention( ScAddress::Convention eConv )
          case ScAddress::CONV_ODF :      SetRefConvention( pConvOOO_A1_ODF ); break;
          case ScAddress::CONV_XL_A1 :    SetRefConvention( pConvXL_A1 );  break;
          case ScAddress::CONV_XL_R1C1 :  SetRefConvention( pConvXL_R1C1 ); break;
@@ -2909,7 +3038,7 @@
      }
  }
  
-@@ -2208,7 +2833,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+@@ -2208,7 +2831,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
                      static const int kQuote = kInc * 2;
                      static const int kPast = kInc * 3;
                      bool bAddToSymbol = true;
@@ -2918,7 +3047,7 @@
                      {
                          // eat it, no sheet name
                          bAddToSymbol = false;
-@@ -2223,7 +2848,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+@@ -2223,7 +2846,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
                      }
                      else if (nRefInSheetName < kPast)
                      {
@@ -2927,7 +3056,7 @@
                              nRefInSheetName += kDollar;
                          else if ('\'' == c)
                          {
-@@ -2545,7 +3170,8 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
+@@ -2545,7 +3168,8 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
  {
      ScRange aRange( aPos, aPos );
      const ScAddress::Details aDetails( pConv->meConv, aPos );
@@ -2937,7 +3066,7 @@
      if( nFlags & SCA_VALID )
      {
          ScRawToken aToken;
-@@ -2564,7 +3190,17 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
+@@ -2564,7 +3188,17 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
              aRef.Ref2.SetTabDeleted( TRUE );        // #REF!
          aRef.Ref2.SetFlag3D( ( nFlags & SCA_TAB2_3D ) != 0 );
          aRef.CalcRelFromAbs( aPos );
@@ -2956,7 +3085,7 @@
          pRawToken = aToken.Clone();
      }
  
-@@ -2576,7 +3212,8 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
+@@ -2576,7 +3210,8 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
  {
      ScAddress aAddr( aPos );
      const ScAddress::Details aDetails( pConv->meConv, aPos );
@@ -2966,7 +3095,7 @@
      // Something must be valid in order to recognize Sheet1.blah or blah.a1
      // as a (wrong) reference.
      if( nFlags & ( SCA_VALID_COL|SCA_VALID_ROW|SCA_VALID_TAB ) )
-@@ -2600,7 +3237,16 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
+@@ -2600,7 +3235,16 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
              nFlags |= SCA_VALID;
          }
          aRef.CalcRelFromAbs( aPos );
@@ -2984,7 +3113,7 @@
          pRawToken = aToken.Clone();
      }
  
-@@ -2708,6 +3354,32 @@ BOOL ScCompiler::IsNamedRange( const String& rUpperName )
+@@ -2708,6 +3352,32 @@ BOOL ScCompiler::IsNamedRange( const String& rUpperName )
          return FALSE;
  }
  
@@ -3017,7 +3146,7 @@
  BOOL ScCompiler::IsDBRange( const String& rName )
  {
      USHORT n;
-@@ -3243,7 +3915,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
+@@ -3243,7 +3913,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
          if (mnPredetectedReference)
          {
              String aStr( cSymbol);
@@ -3026,7 +3155,7 @@
              {
                  /* TODO: it would be nice to generate a #REF! error here, which
                   * would need an ocBad token with additional error value.
-@@ -3306,6 +3978,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
+@@ -3306,6 +3976,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
                && !(bAllowBooleans && IsBoolean( aUpper ))
                && !IsValue( aUpper )
                && !IsNamedRange( aUpper )
@@ -3034,7 +3163,7 @@
                && !IsDBRange( aUpper )
                && !IsColRowName( aUpper )
                && !(bMayBeFuncName && IsMacro( aUpper ))
-@@ -3628,9 +4301,9 @@ BOOL ScCompiler::GetToken()
+@@ -3628,9 +4299,9 @@ BOOL ScCompiler::GetToken()
          else
          {
              if ( nWasColRowName >= 2 && pToken->GetOpCode() == ocColRowName )
@@ -3046,86 +3175,33 @@
              }
          }
      }
-@@ -3641,6 +4314,78 @@ BOOL ScCompiler::GetToken()
+@@ -3641,6 +4312,25 @@ BOOL ScCompiler::GetToken()
      }
      if( pToken->GetOpCode() == ocSubTotal )
          glSubTotal = TRUE;
-+    else if ( pToken->GetOpCode() == ocExternalRef )
++    else if ( pToken->GetOpCode() == ocExternalRef && pToken->GetType() == svExternalName )
 +    {
-+        // Handle external single and double references, or names.
++        // Handle external range names.
 +
 +        ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
 +        const String* pFile = pRefMgr->getExternalFileName(pToken->GetIndex());
 +        if (!pFile)
 +            SetError(errNoName);
 +
-+        switch (pToken->GetType())
-+        {
-+            case svExternalName:
-+            {
-+                const String& rName = pToken->GetString();
-+                ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getRangeNameTokens(pToken->GetIndex(), rName, &aPos);
-+                if (xNew.get())
-+                {
-+                    ScTokenArray* pNew = xNew->Clone();
-+                    PushTokenArray(pNew, true);
-+                    pNew->Reset();
-+                    return GetToken();
-+                }
-+            }
-+            break;
-+            case svExternalSingleRef:
-+            {
-+                SingleRefData aData(pToken->GetSingleRef());
-+                if (aData.IsTabRel())
-+                {
-+                    DBG_ERROR("ScCompiler::GetToken: external single reference must have an absolute table reference!")
-+                    break;
-+                }
-+
-+                aData.CalcAbsIfRel(aPos);
-+                ScAddress aAddr(aData.nCol, aData.nRow, aData.nTab);
-+                ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken(pToken->GetIndex(), pToken->GetString(), aAddr, &aPos, NULL);
-+                if (xNew.get())
-+                {
-+                    pToken = xNew->Clone();
-+                    return true;
-+                }
-+            }
-+            break;
-+            case svExternalDoubleRef:
-+            {
-+                ComplRefData aData(pToken->GetDoubleRef());
-+                if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel())
-+                {
-+                    DBG_ERROR("ScCompiler::GetToken: external double reference must have an absolute table reference!")
-+                    break;
-+                }
++        const String& rName = pToken->GetString();
++        ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getRangeNameTokens(pToken->GetIndex(), rName, &aPos);
++        if (!xNew)
++            SetError(errNoName);
 +
-+                aData.CalcAbsIfRel(aPos);
-+                ScRange aRange(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab, 
-+                               aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab);
-+                ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getDoubleRefTokens(pToken->GetIndex(), pToken->GetString(), aRange, &aPos);
-+                if (xNew.get())
-+                {
-+                    ScTokenArray* pNew = xNew->Clone();
-+                    PushTokenArray(pNew, true);
-+                    pNew->Reset();
-+                    return GetToken();
-+                }
-+            }
-+            break;
-+            default:
-+            {
-+                DBG_ERROR1( "ScCompiler::GetToken: unhandled ocExternalRef type %d", pToken->GetType());
-+            }
-+        }
-+        SetError(errNoName);
++        ScTokenArray* pNew = xNew->Clone();
++        PushTokenArray( pNew, true);
++        pNew->Reset();
++        return GetToken();
 +    }
      else if( pToken->GetOpCode() == ocName )
      {
          ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( pToken->GetIndex() );
-@@ -3796,7 +4541,7 @@ BOOL ScCompiler::GetToken()
+@@ -3796,7 +4486,7 @@ BOOL ScCompiler::GetToken()
                      {   // next defined RowNameRange to the right limits column
                          const ScRange& rRange = pR->GetRange(1);
                          if ( rRange.aStart.Row() <= nRow && nRow <= rRange.aEnd.Row() )
@@ -3134,7 +3210,39 @@
                              SCCOL nTmp = rRange.aStart.Col();
                              if ( nStartCol < nTmp && nTmp <= nMaxCol )
                                  nMaxCol = nTmp - 1;
-@@ -5638,111 +6383,144 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
+@@ -3937,6 +4627,10 @@ BOOL ScCompiler::GetToken()
+ //          SetError(errNoRef);
+         pArr->nRefs++;
+     }
++    else if ( pToken->GetType() == svExternalSingleRef || pToken->GetType() == svExternalDoubleRef )
++    {
++        pArr->nRefs++;
++    }
+     return TRUE;
+ }
+ 
+@@ -4420,6 +5114,11 @@ void ScCompiler::Factor()
+                 bCorrected = TRUE;
+             }
+         }
++        else if ( eOp == ocExternalRef )
++        {
++            PutCode(pToken);
++            eOp = NextToken();
++        }
+         else
+         {
+             SetError( errUnknownToken );
+@@ -4830,7 +5529,7 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
+             else if( t->GetType() != svIndex )  // it may be a DB area!!!
+             {
+                 t->CalcAbsIfRel( rOldPos );
+-                if ( t->GetType() == svSingleRef )
++                if ( t->GetType() == svSingleRef || t->GetType() == svExternalSingleRef )
+                 {
+                     if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos,
+                             r, nDx, nDy, nDz,
+@@ -5638,111 +6337,144 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
          DBG_ERRORFILE("unknown OpCode");
          rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
      }
@@ -3163,15 +3271,15 @@
              {
 -                rRef.CalcAbsIfRel( aPos );
 -                if ( pDoc->HasStringData( rRef.nCol, rRef.nRow, rRef.nTab ) )
--                {
++                case svExternalName:
+                 {
 -                    String aStr;
 -                    pDoc->GetString( rRef.nCol, rRef.nRow, rRef.nTab, aStr );
 -                    EnQuote( aStr );
 -                    rBuffer.append(aStr);
 -                }
 -                else
-+                case svExternalName:
-                 {
+-                {
 -                    rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
 -                    pConv->MakeRefStr (rBuffer, *this, aRef, TRUE );
 +                    const String *pStr = pRefMgr->getExternalFileName(t->GetIndex());
@@ -3365,6 +3473,111 @@
      if( bSpaces )
          rBuffer.append(sal_Unicode(' '));
      if ( bAllowArrAdvance )
+diff --git sc/source/core/tool/interpr4.cxx sc/source/core/tool/interpr4.cxx
+index 5f6faa3..e48178b 100644
+--- sc/source/core/tool/interpr4.cxx
++++ sc/source/core/tool/interpr4.cxx
+@@ -7,7 +7,7 @@
+  * OpenOffice.org - a multi-platform office productivity suite
+  *
+  * $RCSfile: interpr4.cxx,v $
+- * $Revision: 1.57 $
++ * $Revision: 1.57.92.1 $
+  *
+  * This file is part of OpenOffice.org.
+  *
+@@ -74,6 +74,7 @@
+ #include "addinlis.hxx"
+ #include "jumpmatrix.hxx"
+ #include "parclass.hxx"
++#include "externalrefmgr.hxx"
+ 
+ using namespace com::sun::star;
+ 
+@@ -2980,6 +2981,75 @@ void ScInterpreter::ScColRowNameAuto()
+         PushError( errNoRef );
+ }
+ 
++void ScInterpreter::ScExternalRef()
++{
++    ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
++    const String* pFile = pRefMgr->getExternalFileName(pCur->GetIndex());
++    if (!pFile)
++        PushError(errNoName);
++
++    switch (pCur->GetType())
++    {
++        case svExternalSingleRef:
++        {
++            SingleRefData aData(pCur->GetSingleRef());
++            if (aData.IsTabRel())
++            {
++                DBG_ERROR("ScCompiler::GetToken: external single reference must have an absolute table reference!")
++                break;
++            }
++
++            aData.CalcAbsIfRel(aPos);
++            ScAddress aAddr(aData.nCol, aData.nRow, aData.nTab);
++            ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken(
++                pCur->GetIndex(), pCur->GetString(), aAddr, &aPos, NULL);
++
++            if (!xNew)
++                break;
++
++            if (xNew->GetType() == svString)
++                PushString(xNew->GetString());
++            else if (xNew->GetType() == svDouble)
++                PushDouble(xNew->GetDouble());
++            else
++                // Cell in the source doc is empty.  Put 0.
++                PushInt(0);
++
++            return;
++        }
++        break;
++        case svExternalDoubleRef:
++        {
++            ComplRefData aData(pCur->GetDoubleRef());
++            if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel())
++            {
++                DBG_ERROR("ScCompiler::GetToken: external double reference must have an absolute table reference!")
++                break;
++            }
++
++            aData.CalcAbsIfRel(aPos);
++            ScRange aRange(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab,
++                           aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab);
++            ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getDoubleRefTokens(
++                pCur->GetIndex(), pCur->GetString(), aRange, &aPos);
++
++            if (!xNew)
++                break;
++
++            ScToken* p = xNew->First();
++            if (p->GetType() != svMatrix)
++                break;
++
++            PushMatrix(p->GetMatrix());
++            return;
++        }
++        break;
++        default:
++            ;
++    }
++    PushError(errNoRef);
++}
++
+ // --- internals ------------------------------------------------------------
+ 
+ 
+@@ -3412,6 +3482,7 @@ StackVar ScInterpreter::Interpret()
+                 case ocDBArea           : ScDBArea();                   break;
+                 case ocColRowNameAuto   : ScColRowNameAuto();           break;
+ // separated    case ocPush             : Push( (ScToken&) *pCur );     break;
++                case ocExternalRef      : ScExternalRef();              break;
+                 case ocIf               : ScIfJump();                   break;
+                 case ocChose            : ScChoseJump();                break;
+                 case ocAdd              : ScAdd();                      break;
 diff --git sc/source/core/tool/refdata.cxx sc/source/core/tool/refdata.cxx
 index 4ac1814..7ec74d8 100644
 --- sc/source/core/tool/refdata.cxx
@@ -3381,7 +3594,7 @@
  static void lcl_putInOrder( SingleRefData & rRef1, SingleRefData & rRef2 )
  {
 diff --git sc/source/core/tool/token.cxx sc/source/core/tool/token.cxx
-index a20cbd5..87f45c3 100644
+index a20cbd5..3645c87 100644
 --- sc/source/core/tool/token.cxx
 +++ sc/source/core/tool/token.cxx
 @@ -54,6 +54,8 @@
@@ -3918,7 +4131,25 @@
  
  short* ScJumpToken::GetJump() const                     { return pJump; }
  BOOL ScJumpToken::operator==( const ScToken& r ) const
-@@ -1242,6 +1514,9 @@ ScToken* ScTokenArray::GetNextReferenceOrName()
+@@ -1193,6 +1465,8 @@ ScToken* ScTokenArray::GetNextReference()
+         {
+             case svSingleRef:
+             case svDoubleRef:
++            case svExternalSingleRef:
++            case svExternalDoubleRef:
+                 return t;
+             default:
+             {
+@@ -1223,6 +1497,8 @@ ScToken* ScTokenArray::GetNextReferenceRPN()
+         {
+             case svSingleRef:
+             case svDoubleRef:
++            case svExternalSingleRef:
++            case svExternalDoubleRef:
+                 return t;
+             default:
+             {
+@@ -1242,6 +1518,9 @@ ScToken* ScTokenArray::GetNextReferenceOrName()
              case svSingleRef:
              case svDoubleRef:
              case svIndex:
@@ -3928,7 +4159,7 @@
                  return t;
              default:
              {
-@@ -1785,10 +2060,11 @@ ScToken* ScTokenArray::MergeRangeReference( const ScAddress & rPos )
+@@ -1785,10 +2064,11 @@ ScToken* ScTokenArray::MergeRangeReference( const ScAddress & rPos )
      if (!pCode || !nLen)
          return NULL;
      USHORT nIdx = nLen;
@@ -3944,7 +4175,7 @@
      {
          ScTokenRef p = ScToken::ExtendRangeReference( *p1, *p3, rPos, true);
          if (p)
-@@ -1893,6 +2169,21 @@ ScToken* ScTokenArray::AddMatrix( ScMatrix* p )
+@@ -1893,6 +2173,21 @@ ScToken* ScTokenArray::AddMatrix( ScMatrix* p )
      return Add( new ScMatrixToken( p ) );
  }
  
@@ -4801,7 +5032,7 @@
  
  SCTAB XclExpFmlaCompImpl::GetScTab( const SingleRefData& rRefData ) const
 diff --git sc/source/filter/excel/xelink.cxx sc/source/filter/excel/xelink.cxx
-index b1bacad..d929e21 100644
+index b1bacad..b46e813 100644
 --- sc/source/filter/excel/xelink.cxx
 +++ sc/source/filter/excel/xelink.cxx
 @@ -38,6 +38,14 @@
@@ -4947,7 +5178,7 @@
      virtual sal_uInt16  FindExtSheet( sal_Unicode cCode ) = 0;
  
 +    virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
-+                               sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab, 
++                               sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
 +                               XclExpRefLogEntry* pRefLogEntry ) = 0;
 +
      /** Derived classes store all cells in the given range in a CRN record list. */
@@ -4975,7 +5206,7 @@
      virtual sal_uInt16  FindExtSheet( sal_Unicode cCode );
  
 +    virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
-+                               sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab, 
++                               sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
 +                               XclExpRefLogEntry* pRefLogEntry );
 +
      virtual void        StoreCellRange( const SingleRefData& rRef1, const SingleRefData& rRef2 );
@@ -5003,7 +5234,7 @@
      virtual sal_uInt16  FindExtSheet( sal_Unicode cCode );
  
 +    virtual void FindExtSheet( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
-+                               sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab, 
++                               sal_uInt16& rnExtSheet, sal_uInt16& rnFirstSBTab, sal_uInt16& rnLastSBTab,
 +                               XclExpRefLogEntry* pRefLogEntry );
 +
      virtual void        StoreCellRange( const SingleRefData& rRef1, const SingleRefData& rRef2 );
@@ -5042,7 +5273,7 @@
 +
 +void XclExpExtName::WriteAddData( XclExpStream& rStrm )
 +{
-+    // Write only if it only has a single token that is either a cell or cell 
++    // Write only if it only has a single token that is either a cell or cell
 +    // range address.  Excel just writes '02 00 1C 17' for all the other types
 +    // of external names.
 +
@@ -5065,8 +5296,8 @@
 +
 +                bool bColRel = rRef.IsColRel();
 +                bool bRowRel = rRef.IsRowRel();
-+                sal_uInt16 nCol = bColRel ? rRef.nRelCol : rRef.nCol;
-+                sal_uInt16 nRow = bRowRel ? rRef.nRelRow : rRef.nRow;
++                sal_uInt16 nCol = static_cast< sal_uInt16 >( bColRel ? rRef.nRelCol : rRef.nCol );
++                sal_uInt16 nRow = static_cast< sal_uInt16 >( bRowRel ? rRef.nRelRow : rRef.nRow );
 +                if (bColRel) nCol |= 0x4000;
 +                if (bRowRel) nCol |= 0x8000;
 +
@@ -5096,10 +5327,10 @@
 +                bool bCol2Rel = r2.IsColRel();
 +                bool bRow2Rel = r2.IsRowRel();
 +
-+                sal_uInt16 nCol1 = bCol1Rel ? r1.nRelCol : r1.nCol;
-+                sal_uInt16 nCol2 = bCol2Rel ? r2.nRelCol : r2.nCol;
-+                sal_uInt16 nRow1 = bRow1Rel ? r1.nRelRow : r1.nRow;
-+                sal_uInt16 nRow2 = bRow2Rel ? r2.nRelRow : r2.nRow;
++                sal_uInt16 nCol1 = static_cast< sal_uInt16 >( bCol1Rel ? r1.nRelCol : r1.nCol );
++                sal_uInt16 nCol2 = static_cast< sal_uInt16 >( bCol2Rel ? r2.nRelCol : r2.nCol );
++                sal_uInt16 nRow1 = static_cast< sal_uInt16 >( bRow1Rel ? r1.nRelRow : r1.nRow );
++                sal_uInt16 nRow2 = static_cast< sal_uInt16 >( bRow2Rel ? r2.nRelRow : r2.nRow );
 +                if (bCol1Rel) nCol1 |= 0x4000;
 +                if (bRow1Rel) nCol1 |= 0x8000;
 +                if (bCol2Rel) nCol2 |= 0x4000;
@@ -5113,7 +5344,7 @@
 +                // operator token (3B for area reference)
 +                rStrm << static_cast<sal_uInt8>(0x3B);
 +                // range (area) address
-+                sal_uInt16 nSBTab2 = nSBTab + nTab2 - nTab1; 
++                sal_uInt16 nSBTab2 = nSBTab + nTab2 - nTab1;
 +                rStrm << nSBTab << nSBTab2 << nRow1 << nRow2 << nCol1 << nCol2;
 +                return;
 +            }
@@ -5191,16 +5422,16 @@
 +    pMtx->GetDimensions(nCols, nRows);
 +    const ScAddress& s = rRange.aStart;
 +    const ScAddress& e = rRange.aEnd;
-+    if (static_cast<SCCOL>(nCols) != e.Col() - s.Col() + 1 || 
++    if (static_cast<SCCOL>(nCols) != e.Col() - s.Col() + 1 ||
 +        static_cast<SCROW>(nRows) != e.Row() - s.Row() + 1)
 +    {
 +        // size mis-match!
 +        return;
 +    }
 +
-+    for (SCSIZE nCol = 0; nCol < nCols; ++nCol)
++    for (SCCOL nCol = 0; nCol < static_cast< SCCOL >( nCols ); ++nCol)
 +    {
-+        for (SCSIZE nRow = 0; nRow < nRows; ++nRow)
++        for (SCROW nRow = 0; nRow < static_cast< SCROW >( nRows ); ++nRow)
 +        {
 +            if (pMtx->IsString(nCol, nRow))
 +            {
@@ -5697,7 +5928,7 @@
  {
      mxImpl->Save( rStrm );
 diff --git sc/source/filter/excel/xilink.cxx sc/source/filter/excel/xilink.cxx
-index 01932a5..0b79f64 100644
+index 01932a5..9174fd9 100644
 --- sc/source/filter/excel/xilink.cxx
 +++ sc/source/filter/excel/xilink.cxx
 @@ -38,6 +38,13 @@
@@ -5938,7 +6169,7 @@
 +            {
 +                double f = p->GetValue();
 +                ScExternalRefCache::TokenRef pToken(new ScDoubleToken(f));
-+                pCacheTable->setCell(rAddr.mnRow, rAddr.mnCol, pToken);
++                pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
 +            }
 +            break;
 +            case EXC_CACHEDVAL_EMPTY:
@@ -5949,7 +6180,7 @@
 +            {
 +                const String& rStr = p->GetString();
 +                ScExternalRefCache::TokenRef pToken(new ScStringToken(rStr));
-+                pCacheTable->setCell(rAddr.mnRow, rAddr.mnCol, pToken);
++                pCacheTable->setCell(rAddr.mnCol, rAddr.mnRow, pToken);
 +            }
 +            break;
 +            default:
@@ -6031,13 +6262,13 @@
 -        for( sal_uInt16 nSBTab = nSBTabFirst; nSBTab <= nSBTabLast; ++nSBTab )
 -            if( XclImpSupbookTab* pSBTab = maSupbTabList.GetObject( nSBTab ) )
 -                pSBTab->CreateAndFillTable( GetRoot(), aAbsUrl, maFilterName, maFilterOpt );
-+    sal_uInt16 nCount = maSupbTabList.Count();
++    sal_uInt16 nCount = static_cast< sal_uInt16 >( maSupbTabList.Count() );
 +    for (sal_uInt16 i = 0; i < nCount; ++i)
 +    {
 +        XclImpSupbookTab* pTab = maSupbTabList.GetObject(i);
 +        if (!pTab)
 +            return;
-+        
++
 +        const String& rTabName = pTab->GetTabName();
 +        ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
 +        pTab->LoadCachedValues(pCacheTable);
@@ -6123,7 +6354,7 @@
  {
 -    DBG_ASSERT( !mbCreated, "XclImpLinkManager::CreateTables - multiple call" );
 -    if( mbCreated ) return;
-+    // Read all CRN records which can be accessed via XclImpSupbook, and store 
++    // Read all CRN records which can be accessed via XclImpSupbook, and store
 +    // the cached values to the external reference manager.
  
 -    sal_uInt16 nSBTabFirst, nSBTabLast;
@@ -6974,7 +7205,7 @@
  //------------------------------------------------------------------
  
 diff --git sc/source/filter/xml/xmlexprt.cxx sc/source/filter/xml/xmlexprt.cxx
-index 441f463..119a53f 100644
+index 441f463..67c2758 100644
 --- sc/source/filter/xml/xmlexprt.cxx
 +++ sc/source/filter/xml/xmlexprt.cxx
 @@ -68,6 +68,7 @@
@@ -7379,6 +7610,15 @@
  				}
  				if (getExportFlags() & EXPORT_MASTERSTYLES)
  				{
+@@ -2992,7 +3012,7 @@ sal_Bool ScXMLExport::IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2)
+ 							}
+                             // #i29101# number format may be different from column default styles,
+                             // but can lead to different value types, so it must also be compared
+-                            bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) && 
++                            bIsEqual = (aCell1.nNumberFormat == aCell2.nNumberFormat) &&
+                                        (aCell1.fValue == aCell2.fValue);
+ 						}
+ 						break;
 @@ -3333,6 +3353,184 @@ void ScXMLExport::WriteNamedExpressions(const com::sun::star::uno::Reference <co
  	}
  }
@@ -7390,7 +7630,7 @@
 +
 +    ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
 +    pRefMgr->resetSrcFileData();
-+    sal_uInt16 nCount = pRefMgr->getCachedFileCount();
++    sal_uInt16 nCount = pRefMgr->getExternalFileCount();
 +    for (sal_uInt16 nFileId = 0; nFileId < nCount; ++nFileId)
 +    {
 +        const String* pUrl = pRefMgr->getExternalFileName(nFileId);
@@ -7451,7 +7691,7 @@
 +                if (bFirstRow)
 +                {
 +                    if (nRow > 0)
-+                    {   
++                    {
 +                        if (nRow > 1)
 +                        {
 +                            OUStringBuffer aVal;
@@ -7496,7 +7736,7 @@
 +                    if (bFirstCol)
 +                    {
 +                        if (nCol > 0)
-+                        {   
++                        {
 +                            if (nCol > 1)
 +                            {
 +                                OUStringBuffer aVal;
@@ -7522,7 +7762,7 @@
 +                    }
 +
 +                    // Write out this cell.
-+                    ScExternalRefCache::TokenRef pToken = pTable->getCell(nRow, nCol);
++                    ScExternalRefCache::TokenRef pToken = pTable->getCell(nCol, nRow);
 +                    OUString aStrVal;
 +                    if (pToken.get())
 +                    {
@@ -7586,7 +7826,7 @@
  	void CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib);
 diff --git sc/source/filter/xml/xmlexternaltabi.cxx sc/source/filter/xml/xmlexternaltabi.cxx
 new file mode 100644
-index 0000000..3417206
+index 0000000..aae20c2
 --- /dev/null
 +++ sc/source/filter/xml/xmlexternaltabi.cxx
 @@ -0,0 +1,343 @@
@@ -7763,8 +8003,8 @@
 +
 +            if (pToken.get())
 +            {
-+                pTab->setCell(static_cast<SCROW>(
-+                    mrExternalRefInfo.mnRow+i), static_cast<SCCOL>(j), pToken);
++                pTab->setCell(static_cast<SCCOL>(j), 
++                              static_cast<SCROW>(mrExternalRefInfo.mnRow+i), pToken);
 +            }
 +        }
 +    }
@@ -7898,8 +8138,8 @@
 +            aToken.reset(new ScStringToken(maCellString));
 +
 +        mrExternalRefInfo.mpCacheTable->setCell(
-+            static_cast<SCROW>(mrExternalRefInfo.mnRow), 
 +            static_cast<SCCOL>(mrExternalRefInfo.mnCol), 
++            static_cast<SCROW>(mrExternalRefInfo.mnRow), 
 +            aToken);
 +    }
 +}
@@ -8508,10 +8748,10 @@
  
 diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
 new file mode 100644
-index 0000000..20dd943
+index 0000000..bcfa272
 --- /dev/null
 +++ sc/source/ui/docshell/externalrefmgr.cxx
-@@ -0,0 +1,1398 @@
+@@ -0,0 +1,1507 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -8586,11 +8826,34 @@
 +using ::rtl::OUString;
 +using ::std::vector;
 +using ::std::find;
++using ::std::find_if;
 +using ::std::distance;
 +
 +#define SRCDOC_LIFE_SPAN     6000       // 1 minute (in 100th of a sec)
 +#define SRCDOC_SCAN_INTERVAL 1000*5     // every 5 seconds (in msec)
 +
++namespace {
++
++class TabNameSearchPredicate : ::std::unary_function<bool, ScExternalRefCache::TableName>
++{
++public:
++    explicit TabNameSearchPredicate(const String& rSearchName) :
++        maSearchName(ScGlobal::pCharClass->upper(rSearchName))
++    {
++    }
++
++    bool operator()(const ScExternalRefCache::TableName& rTabNameSet) const
++    {
++        // Ok, I'm doing case insensitive search here.
++        return rTabNameSet.maUpperName.Equals(maSearchName);
++    }
++
++private:
++    String maSearchName;
++};
++
++}
++
 +// ============================================================================
 +
 +ScExternalRefCache::Table::Table()
@@ -8601,7 +8864,7 @@
 +{
 +}
 +
-+void ScExternalRefCache::Table::setCell(SCROW nRow, SCCOL nCol, TokenRef pToken)
++void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken)
 +{
 +    using ::std::pair;
 +    RowsDataType::iterator itrRow = maRows.find(nRow);
@@ -8617,13 +8880,13 @@
 +        itrRow = res.first;
 +    }
 +
-+    // Insert this token into the specified column location.  I don't need to 
++    // Insert this token into the specified column location.  I don't need to
 +    // check for existing data.  Just overwrite it.
 +    RowDataType& rRow = itrRow->second;
 +    rRow.insert(RowDataType::value_type(nCol, pToken));
 +}
 +
-+ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCROW nRow, SCCOL nCol) const
++ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCROW nRow) const
 +{
 +    RowsDataType::const_iterator itrTable = maRows.find(nRow);
 +    if (itrTable == maRows.end())
@@ -8755,7 +9018,7 @@
 +        // the table data is not instantiated yet.
 +        return TokenRef();
 +    }
-+    return pTableData->getCell(nRow, nCol);
++    return pTableData->getCell(nCol, nRow);
 +}
 +
 +ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange)
@@ -8807,7 +9070,7 @@
 +        {
 +            for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
 +            {
-+                ScToken* pToken = pTab->getCell(nRow, nCol).get();
++                ScToken* pToken = pTab->getCell(nCol, nRow).get();
 +                if (!pToken)
 +                    return TokenArrayRef();
 +
@@ -8877,7 +9140,7 @@
 +        return;
 +
 +    DocItem& rDoc = *pDocItem;
-+    
++
 +    // See if the table by this name already exists.
 +    TableNameIndexMap::iterator itrTabName = rDoc.maTableNameIndex.find(
 +        ScGlobal::pCharClass->upper(rTabName));
@@ -8889,7 +9152,7 @@
 +    if (!pTableData.get())
 +        pTableData.reset(new Table);
 +
-+    pTableData->setCell(nRow, nCol, pToken);
++    pTableData->setCell(nCol, nRow, pToken);
 +}
 +
 +void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const vector<SingleRangeData>& rData,
@@ -8942,7 +9205,7 @@
 +                else
 +                    pToken.reset(new ScEmptyCellToken(false, false));
 +
-+                pTabData->setCell(nRow, nCol, pToken);
++                pTabData->setCell(nCol, nRow, pToken);
 +            }
 +        }
 +    }
@@ -8977,7 +9240,7 @@
 +
 +    size_t n = rTabNames.size();
 +
-+    // table name list - the list must include all table names in the source 
++    // table name list - the list must include all table names in the source
 +    // document and only to be populated when loading the source document, not
 +    // when loading cached data from, say, Excel XCT/CRN records.
 +    vector<TableName> aNewTabNames;
@@ -8989,8 +9252,8 @@
 +        aNewTabNames.push_back(aNameItem);
 +    }
 +    pDoc->maTableNames.swap(aNewTabNames);
-+    
-+    // data tables - preserve any existing data that may have been set during 
++
++    // data tables - preserve any existing data that may have been set during
 +    // file import.
 +    vector<TableTypeRef> aNewTables(n);
 +    for (size_t i = 0; i < n; ++i)
@@ -9012,6 +9275,14 @@
 +    pDoc->mbInitFromSource = true;
 +}
 +
++String ScExternalRefCache::getTableName(sal_uInt16 nFileId, size_t nCacheId) const
++{
++    if( DocItem* pDoc = getDocItem( nFileId ) )
++        if( nCacheId < pDoc->maTableNames.size() )
++            return pDoc->maTableNames[ nCacheId ].maRealName;
++    return EMPTY_STRING;
++}
++
 +void ScExternalRefCache::getAllTableNames(sal_uInt16 nFileId, vector<String>& rTabNames) const
 +{
 +    rTabNames.clear();
@@ -9026,7 +9297,36 @@
 +        rTabNames.push_back(itr->maRealName);
 +}
 +
-+ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew)
++bool ScExternalRefCache::hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const
++{
++    DocItem* pDoc = getDocItem(nFileId);
++    if (!pDoc)
++        return false;
++
++    String aUpperName = ScGlobal::pCharClass->upper(rTabName);
++    vector<TableName>::const_iterator itrBeg = pDoc->maTableNames.begin(), itrEnd = pDoc->maTableNames.end();
++    vector<TableName>::const_iterator itr = ::std::find_if(
++        itrBeg, itrEnd, TabNameSearchPredicate(aUpperName));
++
++    return itr != itrEnd;
++}
++
++size_t ScExternalRefCache::getCacheTableCount(sal_uInt16 nFileId) const
++{
++    DocItem* pDoc = getDocItem(nFileId);
++    return pDoc ? pDoc->maTables.size() : 0;
++}
++
++ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
++{
++    DocItem* pDoc = getDocItem(nFileId);
++    if (!pDoc || nTabIndex >= pDoc->maTables.size())
++        return TableTypeRef();
++
++    return pDoc->maTables[nTabIndex];
++}
++
++ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex)
 +{
 +    DocItem* pDoc = getDocItem(nFileId);
 +    if (!pDoc)
@@ -9037,18 +9337,23 @@
 +    size_t nIndex;
 +    String aTabNameUpper = ScGlobal::pCharClass->upper(rTabName);
 +    if (lcl_getTableDataIndex(rDoc.maTableNameIndex, aTabNameUpper, nIndex))
++    {
 +        // specified table found.
++        if( pnIndex ) *pnIndex = nIndex;
 +        return rDoc.maTables[nIndex];
++    }
 +
 +    if (!bCreateNew)
 +        return TableTypeRef();
 +
 +    // Specified table doesn't exist yet.  Create one.
++    nIndex = rDoc.maTables.size();
++    if( pnIndex ) *pnIndex = nIndex;
 +    TableTypeRef pTab(new Table);
 +    rDoc.maTables.push_back(pTab);
 +    rDoc.maTableNames.push_back(TableName(aTabNameUpper, rTabName));
 +    rDoc.maTableNameIndex.insert(
-+        TableNameIndexMap::value_type(aTabNameUpper, rDoc.maTables.size()-1));
++        TableNameIndexMap::value_type(aTabNameUpper, nIndex));
 +    return pTab;
 +}
 +
@@ -9187,7 +9492,7 @@
 +    return NULL;
 +}
 +
-+static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange& rRange, 
++static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange& rRange,
 +                                             vector<ScExternalRefCache::SingleRangeData>& rCacheData)
 +{
 +    const ScAddress& s = rRange.aStart;
@@ -9197,9 +9502,17 @@
 +    SCCOL nCol1 = s.Col(), nCol2 = e.Col();
 +    SCROW nRow1 = s.Row(), nRow2 = e.Row();
 +
++    if (nTab2 != nTab1)
++        // For now, we don't support multi-sheet ranges intentionally because
++        // we don't have a way to express them in a single token.  In the
++        // future we can introduce a new stack variable type svMatrixList with
++        // a new token type that can store a 3D matrix value and convert a 3D
++        // range to it.
++        return NULL;
++
 +    auto_ptr<ScTokenArray> pArray(new ScTokenArray);
 +    bool bFirstTab = true;
-+    vector<ScExternalRefCache::SingleRangeData>::iterator 
++    vector<ScExternalRefCache::SingleRangeData>::iterator
 +        itrCache = rCacheData.begin(), itrCacheEnd = rCacheData.end();
 +    for (SCTAB nTab = nTab1; nTab <= nTab2 && itrCache != itrCacheEnd; ++nTab, ++itrCache)
 +    {
@@ -9283,9 +9596,39 @@
 +    clear();
 +}
 +
-+ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew)
++String ScExternalRefManager::getCacheTableName(sal_uInt16 nFileId, size_t nTabIndex) const
++{
++    return maRefCache.getTableName(nFileId, nTabIndex);
++}
++
++ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
++{
++    return maRefCache.getCacheTable(nFileId, nTabIndex);
++}
++
++ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew, size_t* pnIndex)
++{
++    return maRefCache.getCacheTable(nFileId, rTabName, bCreateNew, pnIndex);
++}
++
++void ScExternalRefManager::getAllCachedTableNames(sal_uInt16 nFileId, vector<String>& rTabNames) const
++{
++    maRefCache.getAllTableNames(nFileId, rTabNames);
++}
++
++bool ScExternalRefManager::hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const
++{
++    return maRefCache.hasCacheTable(nFileId, rTabName);
++}
++
++size_t ScExternalRefManager::getCacheTableCount(sal_uInt16 nFileId) const
++{
++    return maRefCache.getCacheTableCount(nFileId);
++}
++
++sal_uInt16 ScExternalRefManager::getExternalFileCount() const
 +{
-+    return maRefCache.getCacheTable(nFileId, rTabName, bCreateNew);
++    return static_cast< sal_uInt16 >( maSrcFiles.size() );
 +}
 +
 +void ScExternalRefManager::storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray)
@@ -9299,7 +9642,7 @@
 +    const ScAddress* pCurPos, SCTAB* pTab)
 +{
 +    if (pCurPos)
-+        insertReferencingCell(nFileId, *pCurPos);
++        insertRefCell(nFileId, *pCurPos);
 +
 +    maybeLinkExternalFile(nFileId);
 +
@@ -9348,7 +9691,7 @@
 +ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
 +{
 +    if (pCurPos)
-+        insertReferencingCell(nFileId, *pCurPos);
++        insertRefCell(nFileId, *pCurPos);
 +
 +    maybeLinkExternalFile(nFileId);
 +
@@ -9391,8 +9734,9 @@
 +    ScExternalRefCache::TokenArrayRef pArray;
 +    pArray.reset(lcl_convertToTokenArray(pSrcDoc, aRange, aCacheData));
 +
-+    // Cache these values.
-+    maRefCache.setCellRangeData(nFileId, rRange, aCacheData, pArray);
++    if (pArray)
++        // Cache these values.
++        maRefCache.setCellRangeData(nFileId, rRange, aCacheData, pArray);
 +
 +    return pArray;
 +}
@@ -9400,7 +9744,7 @@
 +ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos)
 +{
 +    if (pCurPos)
-+        insertReferencingCell(nFileId, *pCurPos);
++        insertRefCell(nFileId, *pCurPos);
 +
 +    maybeLinkExternalFile(nFileId);
 +
@@ -9423,7 +9767,7 @@
 +    if (!pRangeData)
 +        return ScExternalRefCache::TokenArrayRef();
 +
-+    // Parse all tokens in this external range data, and replace each absolute 
++    // Parse all tokens in this external range data, and replace each absolute
 +    // reference token with an external reference token, and cache them.  Also
 +    // register the source document with the link manager if it's a new
 +    // source.
@@ -9459,7 +9803,7 @@
 +            default:
 +                ; // nothing to do
 +        }
-+        
++
 +        if (!bTokenAdded)
 +            pNew->AddToken(*pToken);
 +    }
@@ -9469,7 +9813,7 @@
 +    return pNew;
 +}
 +
-+void ScExternalRefManager::refreshAllReferencingCells(sal_uInt16 nFileId)
++void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId)
 +{
 +    RefCellMap::iterator itr = maRefCells.find(nFileId);
 +    if (itr == maRefCells.end())
@@ -9500,7 +9844,7 @@
 +    pVShell->PaintGrid();
 +}
 +
-+void ScExternalRefManager::insertReferencingCell(sal_uInt16 nFileId, const ScAddress& rCell)
++void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell)
 +{
 +    RefCellMap::iterator itr = maRefCells.find(nFileId);
 +    if (itr != maRefCells.end())
@@ -9576,7 +9920,7 @@
 +    String aFile = pFileData->maFileName;
 +    if (!isFileLoadable(aFile))
 +    {
-+        // The original file path is not loadable.  Try the relative path.  
++        // The original file path is not loadable.  Try the relative path.
 +        // Note that the path is relative to the content.xml substream which
 +        // is one-level higher than the file itself.
 +
@@ -9752,8 +10096,6 @@
 +}
 +sal_uInt16 ScExternalRefManager::getExternalFileId(const String& rFile)
 +{
-+    using namespace std;
-+
 +    vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
 +    vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
 +    if (itr != itrEnd)
@@ -9776,6 +10118,18 @@
 +    return &maSrcFiles[nFileId].maFileName;
 +}
 +
++bool ScExternalRefManager::hasExternalFile(sal_uInt16 nFileId) const
++{
++    return nFileId < maSrcFiles.size();
++}
++
++bool ScExternalRefManager::hasExternalFile(const String& rFile) const
++{
++    vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
++    vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
++    return itr != itrEnd;
++}
++
 +const ScExternalRefManager::SrcFileData* ScExternalRefManager::getExternalFileData(sal_uInt16 nFileId) const
 +{
 +    if (nFileId >= maSrcFiles.size())
@@ -9794,16 +10148,6 @@
 +    return maRefCache.getRealRangeName(nFileId, rRangeName);
 +}
 +
-+void ScExternalRefManager::getAllCachedTableNames(sal_uInt16 nFileId, vector<String>& rTabNames) const
-+{
-+    maRefCache.getAllTableNames(nFileId, rTabNames);
-+}
-+
-+sal_uInt16 ScExternalRefManager::getCachedFileCount() const
-+{
-+    return static_cast<sal_uInt16>(maSrcFiles.size());
-+}
-+
 +template<typename MapContainer>
 +static void lcl_removeByFileId(sal_uInt16 nFileId, MapContainer& rMap)
 +{
@@ -9817,7 +10161,7 @@
 +    removeSrcDocument(nFileId, false);
 +
 +    // Update all cells containing names from this source document.
-+    refreshAllReferencingCells(nFileId);
++    refreshAllRefCells(nFileId);
 +}
 +
 +void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const String& rNewFile)
@@ -9885,6 +10229,11 @@
 +    }
 +}
 +
++void ScExternalRefManager::updateRefCell(const ScAddress& /*rOldPos*/, const ScAddress& /*rNewPos*/)
++{
++    // Implement this.
++}
++
 +void ScExternalRefManager::purgeStaleSrcDocument(sal_Int32 nTimeOut)
 +{
 +    DocShellMap aNewDocShells;
@@ -9892,7 +10241,7 @@
 +    for (; itr != itrEnd; ++itr)
 +    {
 +        // in 100th of a second.
-+        sal_Int32 nSinceLastAccess = (Time() - itr->second.maLastAccess).GetTime(); 
++        sal_Int32 nSinceLastAccess = (Time() - itr->second.maLastAccess).GetTime();
 +        if (nSinceLastAccess < nTimeOut)
 +            aNewDocShells.insert(*itr);
 +    }
@@ -9946,6 +10295,57 @@
          $(SLO)$/tablink.obj   	\
          $(SLO)$/arealink.obj   	\
          $(SLO)$/dbdocfun.obj 	\
+diff --git sc/source/ui/unoobj/cellsuno.cxx sc/source/ui/unoobj/cellsuno.cxx
+index 7e1ec2d..7c0e769 100644
+--- sc/source/ui/unoobj/cellsuno.cxx
++++ sc/source/ui/unoobj/cellsuno.cxx
+@@ -2408,7 +2408,7 @@ void ScCellRangesBase::GetOnePropertyValue( const SfxItemPropertyMap* pMap,
+ 					case ATTR_VALUE_FORMAT:
+ 						{
+ 							ScDocument* pDoc = pDocShell->GetDocument();
+-							
++
+ 							ULONG nOldFormat = ((const SfxUInt32Item&)
+ 									pDataSet->Get( ATTR_VALUE_FORMAT )).GetValue();
+ 							LanguageType eOldLang = ((const SvxLanguageItem&)
+@@ -5176,7 +5176,7 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellRangeObj::getArrayTokens() thr
+                 {
+                     ScTokenArray* pTokenArray = pFCell1->GetCode();
+                     if ( pTokenArray )
+-                        (void)ScTokenConversion::ConvertToTokenSequence( aSequence, *pTokenArray );
++                        (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aSequence, *pTokenArray );
+                 }
+             }
+         }
+@@ -5198,8 +5198,9 @@ void SAL_CALL ScCellRangeObj::setArrayTokens( const uno::Sequence<sheet::Formula
+                 throw uno::RuntimeException();
+             }
+ 
++            ScDocument* pDoc = pDocSh->GetDocument();
+             ScTokenArray aTokenArray;
+-            (void)ScTokenConversion::ConvertToTokenArray( aTokenArray, rTokens );
++            (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, rTokens );
+ 
+             // Actually GRAM_PODF_A1 is a don't-care here because of the token
+             // array being set, it fits with other API compatibility grammars
+@@ -6597,7 +6598,7 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScCellObj::getTokens() throw(uno::Ru
+         {
+             ScTokenArray* pTokenArray = static_cast<ScFormulaCell*>(pCell)->GetCode();
+             if ( pTokenArray )
+-                (void)ScTokenConversion::ConvertToTokenSequence( aSequence, *pTokenArray );
++                (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aSequence, *pTokenArray );
+         }
+ 	}
+     return aSequence;
+@@ -6611,7 +6612,7 @@ void SAL_CALL ScCellObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rT
+ 	{
+ 	    ScDocument* pDoc = pDocSh->GetDocument();
+ 	    ScTokenArray aTokenArray;
+-	    (void)ScTokenConversion::ConvertToTokenArray( aTokenArray, rTokens );
++        (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aTokenArray, rTokens );
+ 
+         ScDocFunc aFunc( *pDocSh );
+         ScBaseCell* pNewCell = new ScFormulaCell( pDoc, aCellPos, &aTokenArray );
 diff --git sc/source/ui/unoobj/docuno.cxx sc/source/ui/unoobj/docuno.cxx
 index 5a8c983..6a2fabf 100644
 --- sc/source/ui/unoobj/docuno.cxx
@@ -9969,17 +10369,56 @@
  		else if ( aString.EqualsAscii( SC_UNO_SHEETLINKS ) )
  		{
  			aRet <<= uno::Reference<container::XNameAccess>(new ScSheetLinksObj( pDocShell ));
+diff --git sc/source/ui/unoobj/fmtuno.cxx sc/source/ui/unoobj/fmtuno.cxx
+index eb9f55b..c41ebe5 100644
+--- sc/source/ui/unoobj/fmtuno.cxx
++++ sc/source/ui/unoobj/fmtuno.cxx
+@@ -197,14 +197,14 @@ void ScTableConditionalFormat::FillFormat( ScConditionalFormat& rFormat,
+         if ( aData.maTokens1.getLength() )
+         {
+             ScTokenArray aTokenArray;
+-            if ( ScTokenConversion::ConvertToTokenArray(aTokenArray, aData.maTokens1) )
++            if ( ScTokenConversion::ConvertToTokenArray(*pDoc, aTokenArray, aData.maTokens1) )
+                 aCoreEntry.SetFormula1(aTokenArray);
+         }
+ 
+         if ( aData.maTokens2.getLength() )
+         {
+             ScTokenArray aTokenArray;
+-            if ( ScTokenConversion::ConvertToTokenArray(aTokenArray, aData.maTokens2) )
++            if ( ScTokenConversion::ConvertToTokenArray(*pDoc, aTokenArray, aData.maTokens2) )
+                 aCoreEntry.SetFormula2(aTokenArray);
+         }
+         rFormat.AddEntry( aCoreEntry );
+@@ -660,14 +660,14 @@ ScValidationData* ScTableValidationObj::CreateValidationData( ScDocument* pDoc,
+     if ( aTokens1.getLength() )
+     {
+         ScTokenArray aTokenArray;
+-        if ( ScTokenConversion::ConvertToTokenArray(aTokenArray, aTokens1) )
++        if ( ScTokenConversion::ConvertToTokenArray(*pDoc, aTokenArray, aTokens1) )
+             pRet->SetFormula1(aTokenArray);
+     }
+ 
+     if ( aTokens2.getLength() )
+     {
+         ScTokenArray aTokenArray;
+-        if ( ScTokenConversion::ConvertToTokenArray(aTokenArray, aTokens2) )
++        if ( ScTokenConversion::ConvertToTokenArray(*pDoc, aTokenArray, aTokens2) )
+             pRet->SetFormula2(aTokenArray);
+     }
+ 
 diff --git sc/source/ui/unoobj/linkuno.cxx sc/source/ui/unoobj/linkuno.cxx
-index 52a5a62..a3c99a5 100644
+index 52a5a62..7131ed4 100644
 --- sc/source/ui/unoobj/linkuno.cxx
 +++ sc/source/ui/unoobj/linkuno.cxx
-@@ -48,8 +48,20 @@
+@@ -48,8 +48,21 @@
  #include "hints.hxx"
  #include "unonames.hxx"
  #include "rangeseq.hxx"
 +#include "token.hxx"
 +
 +#include <vector>
++#include <climits>
  
  using namespace com::sun::star;
 +using ::com::sun::star::uno::Any;
@@ -9994,15 +10433,16 @@
  
  //------------------------------------------------------------------------
  
-@@ -1480,4 +1492,229 @@ uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
+@@ -1480,4 +1493,327 @@ uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
      return xLink;
  }
  
 -//------------------------------------------------------------------------
 +// ============================================================================
 +
-+ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable) :
-+    mpTable(pTable)
++ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable, size_t nIndex) :
++    mpTable(pTable),
++    mnIndex(nIndex)
 +{
 +}
 +
@@ -10028,7 +10468,7 @@
 +        // unidentified value type.
 +        return;
 +
-+    mpTable->setCell(static_cast<SCROW>(nRow), static_cast<SCCOL>(nCol), pToken);
++    mpTable->setCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), pToken);
 +}
 +
 +Any SAL_CALL ScExternalSheetCacheObj::getCellValue(sal_Int32 nCol, sal_Int32 nRow)
@@ -10038,7 +10478,7 @@
 +    if (nRow < 0 || nCol < 0)
 +        throw IllegalArgumentException();
 +
-+    ScToken* pToken = mpTable->getCell(nRow, nCol).get();
++    ScToken* pToken = mpTable->getCell(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow)).get();
 +    if (!pToken)
 +        throw IllegalArgumentException();
 +
@@ -10094,6 +10534,12 @@
 +    return aColsSeq;
 +}
 +
++sal_Int32 SAL_CALL ScExternalSheetCacheObj::getTokenIndex()
++        throw (RuntimeException)
++{
++    return static_cast< sal_Int32 >( mnIndex );
++}
++
 +// ============================================================================
 +
 +ScExternalDocLinkObj::ScExternalDocLinkObj(ScExternalRefManager* pRefMgr, sal_uInt16 nFileId) :
@@ -10110,11 +10556,98 @@
 +        throw (RuntimeException)
 +{
 +    ScUnoGuard aGuard;
-+    ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true);
-+    Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable));
++    size_t nIndex = 0;
++    ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex);
++    Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
 +    return aSheetCache;
 +}
 +
++Any SAL_CALL ScExternalDocLinkObj::getByName(const::rtl::OUString &aName)
++        throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
++{
++    ScUnoGuard aGuard;
++    size_t nIndex = 0;
++    ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false, &nIndex);
++    if (!pTable)
++        throw container::NoSuchElementException();
++
++    Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
++
++    Any aAny;
++    aAny <<= aSheetCache;
++    return aAny;
++}
++
++Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
++        throw (RuntimeException)
++{
++    ScUnoGuard aGuard;
++    vector<String> aTabNames;
++    mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
++    size_t n = aTabNames.size();
++    Sequence<OUString> aSeq(n);
++    for (size_t i = 0; i < n; ++i)
++        aSeq[i] = aTabNames[i];
++    return aSeq;
++}
++
++sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
++        throw (RuntimeException)
++{
++    ScUnoGuard aGuard;
++    return static_cast<sal_Bool>(mpRefMgr->hasCacheTable(mnFileId, aName));
++}
++
++sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
++        throw (RuntimeException)
++{
++    ScUnoGuard aGuard;
++    return static_cast<sal_Int32>(mpRefMgr->getCacheTableCount(mnFileId));
++}
++
++Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nIndex)
++        throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
++{
++    ScUnoGuard aGuard;
++    size_t nTabCount = mpRefMgr->getCacheTableCount(mnFileId);
++    if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(nTabCount))
++        throw lang::IndexOutOfBoundsException();
++
++    ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, static_cast<size_t>(nIndex));
++    if (!pTable)
++        throw lang::IndexOutOfBoundsException();
++
++    Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex));
++
++    Any aAny;
++    aAny <<= aSheetCache;
++    return aAny;
++}
++
++Reference< container::XEnumeration > SAL_CALL ScExternalDocLinkObj::createEnumeration()
++        throw (RuntimeException)
++{
++    ScUnoGuard aGuard;
++    Reference< container::XEnumeration > aRef(
++        new ScIndexEnumeration(this, OUString::createFromAscii(
++            "com.sun.star.sheet.ExternalDocLink")));
++    return aRef;
++}
++
++uno::Type SAL_CALL ScExternalDocLinkObj::getElementType()
++        throw (RuntimeException)
++{
++    ScUnoGuard aGuard;
++    return getCppuType(static_cast<Reference<sheet::XExternalDocLink>*>(0));
++}
++
++sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
++        throw (RuntimeException)
++{
++    ScUnoGuard aGuard;
++    return static_cast<sal_Bool>(mpRefMgr->getCacheTableCount(mnFileId) > 0);
++}
++
 +sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
 +        throw (RuntimeException)
 +{
@@ -10140,68 +10673,72 @@
 +    ScUnoGuard aGuard;
 +    sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aDocName);
 +    Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
-+    maDocLinks.insert( DocLinkMap::value_type(aDocName, aDocLink) );
-+    maDocNames.push_back(aDocName);
 +    return aDocLink;
 +}
 +
-+Any SAL_CALL ScExternalDocLinksObj::getByName(const::rtl::OUString &aName) 
++Any SAL_CALL ScExternalDocLinksObj::getByName(const::rtl::OUString &aName)
 +        throw (container::NoSuchElementException, lang::WrappedTargetException, RuntimeException)
 +{
 +    ScUnoGuard aGuard;
-+    DocLinkMap::const_iterator itr = maDocLinks.find(aName);
-+    if (itr == maDocLinks.end())
++    if (!mpRefMgr->hasExternalFile(aName))
 +        throw container::NoSuchElementException();
 +
++    sal_uInt16 nFileId = mpRefMgr->getExternalFileId(aName);
++    Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
++
 +    Any aAny;
-+    aAny <<= itr->second;
++    aAny <<= aDocLink;
 +    return aAny;
 +}
 +
-+Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames() 
++Sequence< OUString > SAL_CALL ScExternalDocLinksObj::getElementNames()
 +        throw (RuntimeException)
 +{
 +    ScUnoGuard aGuard;
-+    size_t n = maDocNames.size();
++    sal_uInt16 n = mpRefMgr->getExternalFileCount();
 +    Sequence<OUString> aSeq(n);
-+    for (size_t i = 0; i < n; ++i)
-+        aSeq[i] = maDocNames[i];
++    for (sal_uInt16 i = 0; i < n; ++i)
++    {
++        const String* pName = mpRefMgr->getExternalFileName(i);
++        aSeq[i] = pName ? *pName : EMPTY_STRING;
++    }
++
 +    return aSeq;
 +}
 +
-+sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName) 
++sal_Bool SAL_CALL ScExternalDocLinksObj::hasByName(const OUString &aName)
 +        throw (RuntimeException)
 +{
 +    ScUnoGuard aGuard;
-+    return static_cast<sal_Bool>(maDocLinks.count(aName) > 0);
++    return mpRefMgr->hasExternalFile(aName);
 +}
 +
-+sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount() 
++sal_Int32 SAL_CALL ScExternalDocLinksObj::getCount()
 +        throw (RuntimeException)
 +{
 +    ScUnoGuard aGuard;
-+    return static_cast<sal_Int32>(maDocLinks.size());
++    return mpRefMgr->getExternalFileCount();
 +}
 +
-+Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex) 
++Any SAL_CALL ScExternalDocLinksObj::getByIndex(sal_Int32 nIndex)
 +        throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
 +{
 +    ScUnoGuard aGuard;
-+    if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(maDocNames.size()))
++    if (nIndex > ::std::numeric_limits<sal_uInt16>::max() || nIndex < ::std::numeric_limits<sal_uInt16>::min())
 +        throw lang::IndexOutOfBoundsException();
 +
-+    const OUString& rDocName = maDocNames[nIndex];
-+    DocLinkMap::const_iterator itr = maDocLinks.find(rDocName);
-+    if (itr == maDocLinks.end())
-+        // This should never happen!
++    sal_uInt16 nFileId = static_cast<sal_uInt16>(nIndex);
++
++    if (!mpRefMgr->hasExternalFile(nFileId))
 +        throw lang::IndexOutOfBoundsException();
 +
++    Reference< sheet::XExternalDocLink > aDocLink(new ScExternalDocLinkObj(mpRefMgr, nFileId));
 +    Any aAny;
-+    aAny <<= itr->second;
++    aAny <<= aDocLink;
 +    return aAny;
 +}
 +
-+Reference< container::XEnumeration >SAL_CALL ScExternalDocLinksObj::createEnumeration() 
++Reference< container::XEnumeration > SAL_CALL ScExternalDocLinksObj::createEnumeration()
 +        throw (RuntimeException)
 +{
 +    ScUnoGuard aGuard;
@@ -10211,25 +10748,87 @@
 +    return aRef;
 +}
 +
-+uno::Type SAL_CALL ScExternalDocLinksObj::getElementType() 
++uno::Type SAL_CALL ScExternalDocLinksObj::getElementType()
 +        throw (RuntimeException)
 +{
 +    ScUnoGuard aGuard;
 +    return getCppuType(static_cast<Reference<sheet::XExternalDocLinks>*>(0));
 +}
 +
-+sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements() 
++sal_Bool SAL_CALL ScExternalDocLinksObj::hasElements()
 +        throw (RuntimeException)
 +{
 +    ScUnoGuard aGuard;
-+    return static_cast<sal_Bool>(!maDocLinks.empty());
++    return mpRefMgr->getExternalFileCount() > 0;
 +}
 +
+diff --git sc/source/ui/unoobj/nameuno.cxx sc/source/ui/unoobj/nameuno.cxx
+index 1335b36..b303be0 100644
+--- sc/source/ui/unoobj/nameuno.cxx
++++ sc/source/ui/unoobj/nameuno.cxx
+@@ -313,11 +313,11 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScNamedRangeObj::getTokens() throw(u
+     ScUnoGuard aGuard;
+     uno::Sequence<sheet::FormulaToken> aSequence;
+     ScRangeData* pData = GetRangeData_Impl();
+-    if (pData)
++    if (pData && pDocShell)
+     {
+         ScTokenArray* pTokenArray = pData->GetCode();
+         if ( pTokenArray )
+-            (void)ScTokenConversion::ConvertToTokenSequence( aSequence, *pTokenArray );
++            (void)ScTokenConversion::ConvertToTokenSequence( *pDocShell->GetDocument(), aSequence, *pTokenArray );
+     }
+     return aSequence;
+ }
+@@ -325,10 +325,13 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScNamedRangeObj::getTokens() throw(u
+ void SAL_CALL ScNamedRangeObj::setTokens( const uno::Sequence<sheet::FormulaToken>& rTokens ) throw(uno::RuntimeException)
+ {
+     ScUnoGuard aGuard;
+-    ScTokenArray aTokenArray;
+-    (void)ScTokenConversion::ConvertToTokenArray( aTokenArray, rTokens );
+-    // GRAM_PODF_A1 for API compatibility.
+-    Modify_Impl( NULL, &aTokenArray, NULL, NULL, NULL, ScGrammar::GRAM_PODF_A1 );
++    if( pDocShell )
++    {
++        ScTokenArray aTokenArray;
++        (void)ScTokenConversion::ConvertToTokenArray( *pDocShell->GetDocument(), aTokenArray, rTokens );
++        // GRAM_PODF_A1 for API compatibility.
++        Modify_Impl( NULL, &aTokenArray, NULL, NULL, NULL, ScGrammar::GRAM_PODF_A1 );
++    }
+ }
+ 
+ 
 diff --git sc/source/ui/unoobj/tokenuno.cxx sc/source/ui/unoobj/tokenuno.cxx
-index f16b1c5..f968d7b 100644
+index f16b1c5..f515341 100644
 --- sc/source/ui/unoobj/tokenuno.cxx
 +++ sc/source/ui/unoobj/tokenuno.cxx
-@@ -123,6 +123,8 @@ void ScFormulaParserObj::SetCompilerFlags( ScCompiler& rCompiler ) const
+@@ -31,15 +31,16 @@
+ // MARKER(update_precomp.py): autogen include statement, do not remove
+ #include "precompiled_sc.hxx"
+ 
++#include "tokenuno.hxx"
+ 
+ #include <com/sun/star/sheet/ComplexReference.hpp>
++#include <com/sun/star/sheet/ExternalReference.hpp>
+ #include <com/sun/star/sheet/ReferenceFlags.hpp>
+ #include <com/sun/star/sheet/AddressConvention.hpp>
+ #include <com/sun/star/table/CellAddress.hpp>
+ 
+ #include <svtools/itemprop.hxx>
+ 
+-#include "tokenuno.hxx"
+ #include "miscuno.hxx"
+ #include "convuno.hxx"
+ #include "unonames.hxx"
+@@ -48,6 +49,7 @@
+ #include "tokenarray.hxx"
+ #include "docsh.hxx"
+ #include "rangeseq.hxx"
++#include "externalrefmgr.hxx"
+ 
+ using namespace com::sun::star;
+ 
+@@ -123,6 +125,8 @@ void ScFormulaParserObj::SetCompilerFlags( ScCompiler& rCompiler ) const
          eConv = aConvMap[mnConv];
  
      rCompiler.SetRefConvention( eConv );
@@ -10238,7 +10837,25 @@
  }
  
  uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( const rtl::OUString& aFormula )
-@@ -220,6 +222,11 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue(
+@@ -138,7 +142,7 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( co
+         SetCompilerFlags( aCompiler );
+ 
+         ScTokenArray* pCode = aCompiler.CompileString( aFormula );
+-        (void)ScTokenConversion::ConvertToTokenSequence( aRet, *pCode );
++        (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aRet, *pCode );
+         delete pCode;
+     }
+ 
+@@ -155,7 +159,7 @@ rtl::OUString SAL_CALL ScFormulaParserObj::printFormula( const uno::Sequence<she
+     {
+         ScDocument* pDoc = mpDocShell->GetDocument();
+         ScTokenArray aCode;
+-        (void)ScTokenConversion::ConvertToTokenArray( aCode, aTokens );
++        (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aCode, aTokens );
+         ScCompiler aCompiler( pDoc, maRefPos, aCode, pDoc->GetGrammar() );
+         SetCompilerFlags( aCompiler );
+ 
+@@ -220,6 +224,11 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue(
          else
              throw lang::IllegalArgumentException();
      }
@@ -10250,7 +10867,7 @@
      else
          throw beans::UnknownPropertyException();
  }
-@@ -253,6 +260,10 @@ uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPr
+@@ -253,6 +262,10 @@ uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPr
      {
          aRet <<= maOpCodeMapping;
      }
@@ -10261,19 +10878,202 @@
      else
          throw beans::UnknownPropertyException();
      return aRet;
-@@ -473,7 +484,12 @@ bool ScTokenConversion::ConvertToTokenSequence( uno::Sequence<sheet::FormulaToke
+@@ -262,6 +275,27 @@ SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFormulaParserObj )
+ 
+ //------------------------------------------------------------------------
+ 
++void lcl_ExternalRefToCalc( SingleRefData& rRef, const sheet::SingleReference& rAPI )
++{
++    rRef.InitFlags();
++
++    rRef.nCol    = static_cast<SCsCOL>(rAPI.Column);
++    rRef.nRow    = static_cast<SCsROW>(rAPI.Row);
++    rRef.nTab    = 0;
++    rRef.nRelCol = static_cast<SCsCOL>(rAPI.RelativeColumn);
++    rRef.nRelRow = static_cast<SCsROW>(rAPI.RelativeRow);
++    rRef.nRelTab = 0;
++
++    rRef.SetColRel(     ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_RELATIVE ) != 0 );
++    rRef.SetRowRel(     ( rAPI.Flags & sheet::ReferenceFlags::ROW_RELATIVE    ) != 0 );
++    rRef.SetTabRel(     false );    // sheet index must be absolute for external refs
++    rRef.SetColDeleted( ( rAPI.Flags & sheet::ReferenceFlags::COLUMN_DELETED  ) != 0 );
++    rRef.SetRowDeleted( ( rAPI.Flags & sheet::ReferenceFlags::ROW_DELETED     ) != 0 );
++    rRef.SetTabDeleted( false );    // sheet must not be deleted for external refs
++    rRef.SetFlag3D(     ( rAPI.Flags & sheet::ReferenceFlags::SHEET_3D        ) != 0 );
++    rRef.SetRelName(    false );
++}
++
+ void lcl_SingleRefToCalc( SingleRefData& rRef, const sheet::SingleReference& rAPI )
+ {
+     rRef.InitFlags();
+@@ -283,6 +317,25 @@ void lcl_SingleRefToCalc( SingleRefData& rRef, const sheet::SingleReference& rAP
+     rRef.SetRelName(    ( rAPI.Flags & sheet::ReferenceFlags::RELATIVE_NAME   ) != 0 );
+ }
+ 
++void lcl_ExternalRefToApi( sheet::SingleReference& rAPI, const SingleRefData& rRef )
++{
++    rAPI.Column         = rRef.nCol;
++    rAPI.Row            = rRef.nRow;
++    rAPI.Sheet          = 0;
++    rAPI.RelativeColumn = rRef.nRelCol;
++    rAPI.RelativeRow    = rRef.nRelRow;
++    rAPI.RelativeSheet  = 0;
++
++    sal_Int32 nFlags = 0;
++    if ( rRef.IsColRel() )     nFlags |= sheet::ReferenceFlags::COLUMN_RELATIVE;
++    if ( rRef.IsRowRel() )     nFlags |= sheet::ReferenceFlags::ROW_RELATIVE;
++    if ( rRef.IsColDeleted() ) nFlags |= sheet::ReferenceFlags::COLUMN_DELETED;
++    if ( rRef.IsRowDeleted() ) nFlags |= sheet::ReferenceFlags::ROW_DELETED;
++    if ( rRef.IsFlag3D() )     nFlags |= sheet::ReferenceFlags::SHEET_3D;
++    if ( rRef.IsRelName() )    nFlags |= sheet::ReferenceFlags::RELATIVE_NAME;
++    rAPI.Flags = nFlags;
++}
++
+ void lcl_SingleRefToApi( sheet::SingleReference& rAPI, const SingleRefData& rRef )
+ {
+     rAPI.Column         = rRef.nCol;
+@@ -305,8 +358,8 @@ void lcl_SingleRefToApi( sheet::SingleReference& rAPI, const SingleRefData& rRef
+ }
+ 
+ // static
+-bool ScTokenConversion::ConvertToTokenArray( ScTokenArray& rTokenArray,
+-                        const uno::Sequence<sheet::FormulaToken>& rSequence )
++bool ScTokenConversion::ConvertToTokenArray( ScDocument& rDoc,
++        ScTokenArray& rTokenArray, const uno::Sequence<sheet::FormulaToken>& rSequence )
+ {
+     bool bError = false;
+     sal_Int32 nCount = rSequence.getLength();
+@@ -384,6 +437,59 @@ bool ScTokenConversion::ConvertToTokenArray( ScTokenArray& rTokenArray,
+                         else
+                             bError = true;
+                     }
++                    else if ( aType.equals( cppu::UnoType<sheet::ExternalReference>::get() ) )
++                    {
++                        sheet::ExternalReference aApiExtRef;
++                        if( (eOpCode == ocPush) && (rAPI.Data >>= aApiExtRef) && (0 <= aApiExtRef.Index) && (aApiExtRef.Index <= SAL_MAX_UINT16) )
++                        {
++                            sal_uInt16 nFileId = static_cast< sal_uInt16 >( aApiExtRef.Index );
++                            sheet::SingleReference aApiSRef;
++                            sheet::ComplexReference aApiCRef;
++                            ::rtl::OUString aName;
++                            if( aApiExtRef.Reference >>= aApiSRef )
++                            {
++                                // try to resolve cache index to sheet name
++                                size_t nCacheId = static_cast< size_t >( aApiSRef.Sheet );
++                                String aTabName = rDoc.GetExternalRefManager()->getCacheTableName( nFileId, nCacheId );
++                                if( aTabName.Len() > 0 )
++                                {
++                                    SingleRefData aSingleRef;
++                                    // convert column/row settings, set sheet index to absolute
++                                    lcl_ExternalRefToCalc( aSingleRef, aApiSRef );
++                                    rTokenArray.AddExternalSingleReference( nFileId, aTabName, aSingleRef );
++                                }
++                                else
++                                    bError = true;
++                            }
++                            else if( aApiExtRef.Reference >>= aApiCRef )
++                            {
++                                // try to resolve cache index to sheet name. TODO: second cache index is dropped
++                                size_t nCacheId = static_cast< size_t >( aApiCRef.Reference1.Sheet );
++                                String aTabName = rDoc.GetExternalRefManager()->getCacheTableName( nFileId, nCacheId );
++                                if( aTabName.Len() > 0 )
++                                {
++                                    ComplRefData aComplRef;
++                                    // convert column/row settings, set sheet index to absolute
++                                    lcl_ExternalRefToCalc( aComplRef.Ref1, aApiCRef.Reference1 );
++                                    lcl_ExternalRefToCalc( aComplRef.Ref2, aApiCRef.Reference2 );
++                                    rTokenArray.AddExternalDoubleReference( nFileId, aTabName, aComplRef );
++                                }
++                                else
++                                    bError = true;
++                            }
++                            else if( aApiExtRef.Reference >>= aName )
++                            {
++                                if( aName.getLength() > 0 )
++                                    rTokenArray.AddExternalName( nFileId, aName );
++                                else
++                                    bError = true;
++                            }
++                            else
++                                bError = true;
++                        }
++                        else
++                            bError = true;
++                    }
+                     else
+                         bError = true;      // unknown struct
+                 }
+@@ -414,8 +520,8 @@ bool ScTokenConversion::ConvertToTokenArray( ScTokenArray& rTokenArray,
+ }
+ 
+ // static
+-bool ScTokenConversion::ConvertToTokenSequence( uno::Sequence<sheet::FormulaToken>& rSequence,
+-                        const ScTokenArray& rTokenArray )
++bool ScTokenConversion::ConvertToTokenSequence( ScDocument& rDoc,
++        uno::Sequence<sheet::FormulaToken>& rSequence, const ScTokenArray& rTokenArray )
+ {
+     bool bError = false;
+ 
+@@ -430,7 +536,7 @@ bool ScTokenConversion::ConvertToTokenSequence( uno::Sequence<sheet::FormulaToke
+             sheet::FormulaToken& rAPI = rSequence[nPos];
+ 
+             OpCode eOpCode = rToken.GetOpCode();
+-            rAPI.OpCode = static_cast<sal_Int32>(eOpCode);      //! assuming equal values for the moment
++            // eOpCode may be changed in the following switch/case
+             switch ( rToken.GetType() )
+             {
+                 case svByte:
+@@ -473,9 +579,50 @@ bool ScTokenConversion::ConvertToTokenSequence( uno::Sequence<sheet::FormulaToke
                      if (!ScRangeToSequence::FillMixedArray( rAPI.Data, rToken.GetMatrix(), true))
                          rAPI.Data.clear();
                      break;
 +                case svExternalSingleRef:
++                    {
++                        sheet::SingleReference aSingleRef;
++                        lcl_ExternalRefToApi( aSingleRef, rToken.GetSingleRef() );
++                        size_t nCacheId;
++                        rDoc.GetExternalRefManager()->getCacheTable( rToken.GetIndex(), rToken.GetString(), false, &nCacheId );
++                        aSingleRef.Sheet = static_cast< sal_Int32 >( nCacheId );
++                        sheet::ExternalReference aExtRef;
++                        aExtRef.Index = rToken.GetIndex();
++                        aExtRef.Reference <<= aSingleRef;
++                        rAPI.Data <<= aExtRef;
++                        eOpCode = ocPush;
++                    }
++                    break;
 +                case svExternalDoubleRef:
++                    {
++                        sheet::ComplexReference aComplRef;
++                        lcl_ExternalRefToApi( aComplRef.Reference1, rToken.GetSingleRef() );
++                        lcl_ExternalRefToApi( aComplRef.Reference2, rToken.GetSingleRef2() );
++                        size_t nCacheId;
++                        rDoc.GetExternalRefManager()->getCacheTable( rToken.GetIndex(), rToken.GetString(), false, &nCacheId );
++                        aComplRef.Reference1.Sheet = aComplRef.Reference2.Sheet = static_cast< sal_Int32 >( nCacheId );
++                        sheet::ExternalReference aExtRef;
++                        aExtRef.Index = rToken.GetIndex();
++                        aExtRef.Reference <<= aComplRef;
++                        rAPI.Data <<= aExtRef;
++                        eOpCode = ocPush;
++                    }
++                    break;
 +                case svExternalName:
-+                // FIXME: svExternal... are to be transported via API.
++                    {
++                        sheet::ExternalReference aExtRef;
++                        aExtRef.Index = rToken.GetIndex();
++                        aExtRef.Reference <<= ::rtl::OUString( rToken.GetString() );
++                        rAPI.Data <<= aExtRef;
++                        eOpCode = ocPush;
++                    }
++                    break;
                  default:
 +                    DBG_ERROR1( "ScTokenConversion::ConvertToTokenSequence: unhandled token type SvStackVar %d", rToken.GetType());
++                case svSep:
                      rAPI.Data.clear();      // no data
              }
++            rAPI.OpCode = static_cast<sal_Int32>(eOpCode);      //! assuming equal values for the moment
          }
+     }
+     else
 diff --git sc/source/ui/view/tabvwsh4.cxx sc/source/ui/view/tabvwsh4.cxx
 index 436f0eb..2bf1f26 100644
 --- sc/source/ui/view/tabvwsh4.cxx



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]