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



Author: kyoshida
Date: Wed Sep  3 00:32:12 2008
New Revision: 13762
URL: http://svn.gnome.org/viewvc/ooo-build?rev=13762&view=rev

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

	* patches/dev300/calc-external-defined-names-offapi.diff:
	* patches/dev300/calc-external-defined-names-sc.diff: updated, with 
	more change from the upstream, updated API, and more.
	
	* patches/dev300/apply:
	* patches/dev300/calc-external-names-additional-fixes.diff: removed, as
	this has been combined with the -sc.diff patch above.


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

Modified: trunk/patches/dev300/apply
==============================================================================
--- trunk/patches/dev300/apply	(original)
+++ trunk/patches/dev300/apply	Wed Sep  3 00:32:12 2008
@@ -1724,7 +1724,6 @@
 # Implement external range names.
 calc-external-defined-names-sc.diff, i#3740, i#4385, n#355685, kohei
 calc-external-defined-names-offapi.diff, i#3740, i#4385, n#355685, kohei
-calc-external-names-additional-fixes.diff, kohei
 
 [ CalcSolver ]
 SectionOwner => kohei

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	Wed Sep  3 00:32:12 2008
@@ -1,9 +1,9 @@
 diff --git offapi/com/sun/star/sheet/ExternalDocLink.idl offapi/com/sun/star/sheet/ExternalDocLink.idl
 new file mode 100644
-index 0000000..7320905
+index 0000000..9c7f70d
 --- /dev/null
 +++ offapi/com/sun/star/sheet/ExternalDocLink.idl
-@@ -0,0 +1,53 @@
+@@ -0,0 +1,57 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -41,6 +41,8 @@
 +
 +module com {  module sun {  module star {  module sheet {
 +
++//=============================================================================
++
 +/** Represents a single external document link. 
 +
 +    <p>An external document link contains cached data used for external cell
@@ -54,6 +56,8 @@
 +{
 +};
 +
++//=============================================================================
++
 +}; }; }; };
 +
 +#endif
@@ -118,6 +122,262 @@
 +}; }; }; };
 +
 +#endif
+diff --git offapi/com/sun/star/sheet/ExternalLinkInfo.idl offapi/com/sun/star/sheet/ExternalLinkInfo.idl
+new file mode 100644
+index 0000000..52758ec
+--- /dev/null
++++ offapi/com/sun/star/sheet/ExternalLinkInfo.idl
+@@ -0,0 +1,81 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: ExternalLinkInfo.idl,v $
++ * $Revision: 1.1.2.2 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++#ifndef __com_sun_star_sheet_ExternalLinkInfo_idl__
++#define __com_sun_star_sheet_ExternalLinkInfo_idl__
++
++#ifndef __com_sun_star_sheet_ExternalLinkType_idl__
++#include <com/sun/star/sheet/ExternalLinkType.idl>
++#endif
++
++//=============================================================================
++
++module com {  module sun {  module star {  module sheet {
++
++//=============================================================================
++/** describes an external link in a formula.
++
++    @since OOo3.1
++ */
++struct ExternalLinkInfo
++{
++    //-------------------------------------------------------------------------
++
++    /** Link type, one of <type>ExternalLinkType</type> constants.
++     */
++
++    long Type;
++
++    //-------------------------------------------------------------------------
++
++    /** Location of this link type.
++
++        Modes used:
++
++        1.  If <member>Type</member> is <const>ExternalLinkType::EXTERNAL</const>,
++            this member shall contain a string with the <b>URI</b> of a
++            document. The formula that would need this information for example
++            would contain =[1]Sheet1!A1 or ='[1]Sheet name'!A1 where [1] does
++            resolve to the URI contained in this Location member. Note that
++            the quotes cover both, the document name and the sheet name.
++
++        2.  If <member>Type</member> is <type>ExternalLinkType::DDE</type>,
++            this member shall contain a <type>DDELinkType</type> describing
++            service name, topic, and all known items of a DDE link.
++     */
++
++    any Data;
++
++};
++
++//=============================================================================
++
++}; }; }; };
++
++#endif
+diff --git offapi/com/sun/star/sheet/ExternalLinkType.idl offapi/com/sun/star/sheet/ExternalLinkType.idl
+new file mode 100644
+index 0000000..7c1b040
+--- /dev/null
++++ offapi/com/sun/star/sheet/ExternalLinkType.idl
+@@ -0,0 +1,67 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ * 
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: ExternalLinkType.idl,v $
++ * $Revision: 1.1.2.1 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef __com_sun_star_sheet_ExternalLinkType_idl__
++#define __com_sun_star_sheet_ExternalLinkType_idl__
++
++//=============================================================================
++
++module com {  module sun {  module star {  module sheet {
++
++//=============================================================================
++
++/** Constants designating the link type in
++    <type>ExternalLinkInfo</type>, used with
++    <member>FormulaParser::ExternalLinks</member>.
++
++    @since OOo3.1
++ */
++constants ExternalLinkType
++{
++    /** Unknown element type
++     */
++    const long UNKNOWN  = 0;
++
++    /** URL of an external document.
++     */
++    const long DOCUMENT = 1;
++
++    /** DDE link.
++     */
++    const long DDE      = 2;
++
++};
++
++//=============================================================================
++
++}; }; }; };
++
++#endif
++
+diff --git offapi/com/sun/star/sheet/ExternalReference.idl offapi/com/sun/star/sheet/ExternalReference.idl
+new file mode 100644
+index 0000000..a2bc3c7
+--- /dev/null
++++ offapi/com/sun/star/sheet/ExternalReference.idl
+@@ -0,0 +1,90 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: ExternalLinkInfo.idl,v $
++ * $Revision: 1.1.2.2 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef __com_sun_star_sheet_ExternalReference_idl__
++#define __com_sun_star_sheet_ExternalReference_idl__
++
++module com {  module sun {  module star {  module sheet {
++
++//=============================================================================
++
++/** 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.
++
++    @since OOo 3.1
++ */
++struct ExternalReference
++{
++    //-------------------------------------------------------------------------
++
++    /** 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> 
++        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;
++    
++    //-------------------------------------------------------------------------
++
++    /** Name of the sheet that the external reference points to.
++
++        <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 
++        sheet-specific range name.</i></p>
++     */
++    string SheetName;
++
++    //-------------------------------------------------------------------------
++
++    /** 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.
++
++        @see com::sun::star::sheet::SingleReference
++        @see com::sun::star::sheet::ComplexReference
++     */
++    any Reference;
++};
++
++//=============================================================================
++
++}; }; }; };
++
++#endif
 diff --git offapi/com/sun/star/sheet/ExternalSheetCache.idl offapi/com/sun/star/sheet/ExternalSheetCache.idl
 new file mode 100644
 index 0000000..17af156
@@ -179,12 +439,25 @@
 +}; }; }; };
 +
 +#endif
+diff --git offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl
+index 20369b2..6fa02d0 100644
+--- offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl
++++ offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl
+@@ -59,6 +59,8 @@ constants FormulaMapGroupSpecialOffset
+     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;
+ };
+ 
+ //=============================================================================
 diff --git offapi/com/sun/star/sheet/XExternalDocLink.idl offapi/com/sun/star/sheet/XExternalDocLink.idl
 new file mode 100644
-index 0000000..65928c5
+index 0000000..0f3e02b
 --- /dev/null
 +++ offapi/com/sun/star/sheet/XExternalDocLink.idl
-@@ -0,0 +1,62 @@
+@@ -0,0 +1,84 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -222,6 +495,8 @@
 +
 +module com {  module sun {  module star {  module sheet {
 +
++//=============================================================================
++
 +/** Primary interface for the <type scope="com::sun::star::sheet">ExternalDocLink</type> service.
 +   
 +    @see com::sun::star::sheet::ExternalDocLink
@@ -230,6 +505,8 @@
 + */
 +interface XExternalDocLink
 +{
++    //-------------------------------------------------------------------------
++
 +    /** <p>This method adds a new sheet cache instance to the extternal document 
 +        link for a specified sheet name.  If a sheet cache instance already 
 +        exists for the specified name, then the existing instance is returned.</p>
@@ -242,8 +519,26 @@
 +        @return com::sun::star::sheet::XExternalSheetCache sheet cache instance
 +     */
 +    com::sun::star::sheet::XExternalSheetCache addSheetCache( [in] string aSheetName );
++
++    //-------------------------------------------------------------------------
++
++    /** Index corresponding to the external document link.
++    
++        <p>This index value corresponds with the external document 
++        represented by an instance of 
++        <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>
++
++        @see com::sun::star::sheet::FormulaToken
++        @see com::sun::star::sheet::FormulaMapGroupSpecialOffset::EXTERNAL_REFERENCE
++     */
++    [attribute, readonly] long TokenIndex;
 +};
 +
++//=============================================================================
++
 +}; }; }; };
 +
 +#endif
@@ -410,20 +705,23 @@
 +
 +#endif
 diff --git offapi/com/sun/star/sheet/makefile.mk offapi/com/sun/star/sheet/makefile.mk
-index c1d2844..16dffda 100644
+index c1d2844..09b33e7 100644
 --- offapi/com/sun/star/sheet/makefile.mk
 +++ offapi/com/sun/star/sheet/makefile.mk
-@@ -123,6 +123,9 @@ IDLFILES=\
+@@ -123,6 +123,12 @@ IDLFILES=\
  	DatabaseRangesEnumeration.idl\
  	DDELinkMode.idl\
  	DocumentSettings.idl\
 +	ExternalDocLink.idl\
 +	ExternalDocLinks.idl\
++	ExternalLinkInfo.idl\
++	ExternalLinkType.idl\
++	ExternalReference.idl\
 +	ExternalSheetCache.idl\
  	FillDateMode.idl\
  	FillDirection.idl\
  	FillMode.idl\
-@@ -255,6 +258,9 @@ IDLFILES=\
+@@ -255,6 +261,9 @@ IDLFILES=\
  	XDocumentAuditing.idl\
  	XDrillDownDataSupplier.idl\
  	XEnhancedMouseClickBroadcaster.idl\

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	Wed Sep  3 00:32:12 2008
@@ -1,8 +1,23 @@
 diff --git sc/inc/address.hxx sc/inc/address.hxx
-index f92fc8e..f15a341 100644
+index f92fc8e..9757898 100644
 --- sc/inc/address.hxx
 +++ sc/inc/address.hxx
-@@ -287,6 +287,15 @@ public:
+@@ -44,6 +44,14 @@
+ #endif
+ #include "scdllapi.h"
+ 
++#include <com/sun/star/uno/Sequence.hxx>
++
++namespace com { namespace sun { namespace star {
++    namespace sheet {
++        struct ExternalLinkInfo;
++    }
++}}}
++
+ class ScDocument;
+ 
+ // The typedefs
+@@ -287,6 +295,15 @@ public:
      };
      static const Details detailsOOOa1;
  
@@ -18,29 +33,36 @@
      inline ScAddress() : nRow(0), nCol(0), nTab(0) {}
      inline ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
          : nRow(nRowP), nCol(nColP), nTab(nTabP)
-@@ -317,8 +326,8 @@ public:
+@@ -317,8 +334,12 @@ public:
      inline void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
      { nColP = nCol; nRowP = nRow; nTabP = nTab; }
  
 -    USHORT Parse( const String&, ScDocument* = NULL,
 -                  const Details& rDetails = detailsOOOa1);
 +    USHORT Parse( const String&, ScDocument* = NULL, 
-+                  const Details& rDetails = detailsOOOa1, ExternalInfo* pExtInfo = NULL);
++                  const Details& rDetails = detailsOOOa1,
++                  ExternalInfo* pExtInfo = NULL,
++                  const ::com::sun::star::uno::Sequence<
++                    const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
++
      void Format( String&, USHORT = 0, ScDocument* = NULL,
                   const Details& rDetails = detailsOOOa1) const;
  
-@@ -463,7 +472,8 @@ public:
+@@ -463,7 +484,11 @@ public:
      inline bool In( const ScRange& ) const;     // is Range& in Range?
  
      USHORT Parse( const String&, ScDocument* = NULL,
 -                  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
 +                  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
-+                  ScAddress::ExternalInfo* pExtInfo = NULL );
++                  ScAddress::ExternalInfo* pExtInfo = NULL,
++                  const ::com::sun::star::uno::Sequence<
++                    const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
++
      USHORT ParseAny( const String&, ScDocument* = NULL,
                       const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
      USHORT ParseCols( const String&, ScDocument* = NULL,
 diff --git sc/inc/compiler.hrc sc/inc/compiler.hrc
-index 92b7e82..22d77cb 100644
+index 92b7e82..ec67599 100644
 --- sc/inc/compiler.hrc
 +++ sc/inc/compiler.hrc
 @@ -39,25 +39,26 @@
@@ -66,7 +88,7 @@
 -#define SC_OPCODE_ARRAY_ROW_SEP      21
 -#define SC_OPCODE_ARRAY_COL_SEP      22     /* some convs use sep != col_sep */
 -#define SC_OPCODE_STOP_DIV           23
-+#define SC_OPCODE_EXTERNAL_NAME       5
++#define SC_OPCODE_EXTERNAL_REF        5
 +#define SC_OPCODE_IF                  6     /* jump commands */
 +#define SC_OPCODE_CHOSE               7
 +#define SC_OPCODE_OPEN                8     /* parentheses and separators */
@@ -90,18 +112,30 @@
  /*** error constants #... ***/
  #define SC_OPCODE_START_ERRORS       30
 diff --git sc/inc/compiler.hxx sc/inc/compiler.hxx
-index 7bb6767..85fdf91 100644
+index 7bb6767..bdffc05 100644
 --- sc/inc/compiler.hxx
 +++ sc/inc/compiler.hxx
-@@ -45,6 +45,7 @@
+@@ -45,6 +45,8 @@
  #include <unotools/charclass.hxx>
  #include <rtl/ustrbuf.hxx>
  #include <com/sun/star/uno/Sequence.hxx>
++#include <com/sun/star/sheet/ExternalLinkInfo.hpp>
 +#include <vector>
  
  namespace com { namespace sun { namespace star {
      namespace sheet {
-@@ -100,6 +101,7 @@ namespace com { namespace sun { namespace star {
+@@ -88,8 +90,8 @@ namespace com { namespace sun { namespace star {
+ #define SC_COMPILER_C_VALUE_VALUE   0x00002000
+ #define SC_COMPILER_C_STRING_SEP    0x00004000
+ #define SC_COMPILER_C_NAME_SEP      0x00008000  // there can be only one! '\''
+-#define SC_COMPILER_C_CHAR_IDENT    0x00010000  // identifier (built-in function) start
+-#define SC_COMPILER_C_IDENT         0x00020000  // identifier continuation
++#define SC_COMPILER_C_CHAR_IDENT    0x00010000  // identifier (built-in function) or reference start
++#define SC_COMPILER_C_IDENT         0x00020000  // identifier or reference continuation
+ #define SC_COMPILER_C_ODF_LBRACKET  0x00040000  // ODF '[' reference bracket
+ #define SC_COMPILER_C_ODF_RBRACKET  0x00080000  // ODF ']' reference bracket
+ #define SC_COMPILER_C_ODF_LABEL_OP  0x00100000  // ODF '!!' automatic intersection of labels
+@@ -100,6 +102,7 @@ namespace com { namespace sun { namespace star {
  class ScDocument;
  class ScMatrix;
  class ScRangeData;
@@ -109,7 +143,7 @@
  
  // constants and data types internal to compiler
  
-@@ -151,6 +153,15 @@ public:
+@@ -151,6 +154,15 @@ public:
              bool        bHasForceArray;
          } sbyte;
          ComplRefData aRef;
@@ -125,7 +159,7 @@
          ScMatrix*    pMat;
          USHORT       nIndex;                // index into name collection
          sal_Unicode  cStr[ MAXSTRLEN+1 ];   // string (up to 255 characters + 0)
-@@ -180,6 +191,9 @@ public:
+@@ -180,6 +192,9 @@ public:
      void SetDouble( double fVal );
      void SetInt( int nVal );
      void SetName( USHORT n );
@@ -135,7 +169,7 @@
      void SetMatrix( ScMatrix* p );
      void SetExternal(const sal_Unicode* pStr);
      // These methods are ok to use, reference count not cleared.
-@@ -228,6 +242,24 @@ public:
+@@ -228,6 +243,24 @@ public:
                                     xub_StrLen nSrcPos,
                                     const CharClass* pCharClass) const = 0;
  
@@ -160,7 +194,25 @@
          enum SpecialSymbolType
          {
              /** 
-@@ -448,6 +480,7 @@ private:
+@@ -372,6 +405,7 @@ private:
+     static const Convention * const pConvOOO_A1_ODF;
+     static const Convention * const pConvXL_A1;
+     static const Convention * const pConvXL_R1C1;
++    static const Convention * const pConvXL_OOX;
+ 
+     static struct AddInMap
+     {
+@@ -387,6 +421,9 @@ private:
+     ScDocument* pDoc;
+     ScAddress   aPos;
+ 
++    // For ScAddress::CONV_XL_OOX, may be set via API by MOOXML filter.
++    ::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::ExternalLinkInfo > maExternalLinks;
++
+     String      aCorrectedFormula;                  // autocorrected Formula
+     String      aCorrectedSymbol;                   // autocorrected Symbol
+     sal_Unicode cSymbol[MAXSTRLEN];                 // current Symbol
+@@ -448,6 +485,7 @@ private:
      BOOL IsDoubleReference( const String& );
      BOOL IsMacro( const String& );
      BOOL IsNamedRange( const String& );
@@ -168,6 +220,36 @@
      BOOL IsDBRange( const String& );
      BOOL IsColRowName( const String& );
      BOOL IsBoolean( const String& );
+@@ -540,6 +578,29 @@ public:
+     void            SetGrammar( const ScGrammar::Grammar eGrammar );
+     inline  ScGrammar::Grammar   GetGrammar() const { return meGrammar; }
+ 
++private:
++    /** Set grammar and reference convention from within SetFormulaLanguage()
++        or SetGrammar().
++        
++        @param eNewGrammar
++            The new grammar to be set and the associated reference convention.
++
++        @param eOldGrammar
++            The previous grammar that was active before SetFormulaLanguage().
++     */
++    void            SetGrammarAndRefConvention(
++                        const ScGrammar::Grammar eNewGrammar,
++                        const ScGrammar::Grammar eOldGrammar );
++public:
++
++    /// Set external link info for ScAddress::CONV_XL_OOX.
++    inline  void    SetExternalLinks(
++            const ::com::sun::star::uno::Sequence<
++            const ::com::sun::star::sheet::ExternalLinkInfo > & rLinks )
++    {
++        maExternalLinks = rLinks;
++    }
++
+     void            SetExtendedErrorDetection( bool bVal ) { mbExtendedErrorDetection = bVal; }
+ 
+     BOOL            IsCorrected() { return bCorrected; }
 diff --git sc/inc/document.hxx sc/inc/document.hxx
 index a01f09b..5d4ca1f 100644
 --- sc/inc/document.hxx
@@ -207,10 +289,10 @@
  
 diff --git sc/inc/externalrefmgr.hxx sc/inc/externalrefmgr.hxx
 new file mode 100644
-index 0000000..46d691d
+index 0000000..c094e14
 --- /dev/null
 +++ sc/inc/externalrefmgr.hxx
-@@ -0,0 +1,382 @@
+@@ -0,0 +1,383 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -348,17 +430,18 @@
 +     *         not need to delete this instance since its life cycle is
 +     *         managed by this class.</i>
 +     */
-+    ScToken* getCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol);
++    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 
-+     *         manage the life cycle of the returned instance</i>.
++     *         manage the life cycle of the returned instance</i>, which is
++     *         guaranteed if the TokenArrayRef is properly used..
 +     */
-+    ScTokenArray* getCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange);
++    ScExternalRefCache::TokenArrayRef getCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange);
 +
-+    ScTokenArray* getRangeNameTokens(sal_uInt16 nFileId, const String& rName);
++    ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName);
 +    void setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray);
 +
 +    void setCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol, TokenRef pToken);
@@ -388,9 +471,9 @@
 +     * @param nFileId file ID
 +     * @param rTabName table name
 +     * 
-+     * @return pointer to the cache table instance
++     * @return shared_ptr to the cache table instance
 +     */
-+    Table* getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew);
++    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew);
 +
 +    void clearCache(sal_uInt16 nFileId);
 +
@@ -462,10 +545,10 @@
 +    explicit ScExternalRefManager(ScDocument* pDoc);
 +    ~ScExternalRefManager();
 +
-+    ScExternalRefCache::Table* getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew = true);
++    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew = true);
 +    void storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray);
 +
-+    ScToken* getSingleRefToken(sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell, const ScAddress* pCurPos, SCTAB* pTab);
++    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 
@@ -477,10 +560,10 @@
 +     * @param pCurPos current cursor position to keep track of cells that 
 +     *                reference an external data.
 +     * 
-+     * @return pointer 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>
 +     */
-+    ScTokenArray* getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos);
++    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 
@@ -491,9 +574,9 @@
 +     *                external names for refreshing purposes.  If this is
 +     *                NULL, then the cell will not be added to the list.
 +     * 
-+     * @return array of tokens composing the name
++     * @return shared_ptr to array of tokens composing the name
 +     */
-+    ScTokenArray* getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos = NULL);
++    ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos = NULL);
 +
 +    const String& getOwnDocumentName() const;
 +    bool isOwnDocument(const String& rFile) const;
@@ -594,7 +677,7 @@
 +
 +#endif
 diff --git sc/inc/linkuno.hxx sc/inc/linkuno.hxx
-index b6fc524..926fed7 100644
+index b6fc524..586986e 100644
 --- sc/inc/linkuno.hxx
 +++ sc/inc/linkuno.hxx
 @@ -36,6 +36,9 @@
@@ -623,7 +706,7 @@
  
  class ScAreaLink;
  class ScDocShell;
-@@ -493,8 +501,108 @@ public:
+@@ -493,8 +501,112 @@ public:
  								throw(::com::sun::star::uno::RuntimeException);
  };
  
@@ -632,7 +715,7 @@
 +class ScExternalSheetCacheObj : public cppu::WeakImplHelper1< ::com::sun::star::sheet::XExternalSheetCache >
 +{
 +public:
-+    explicit ScExternalSheetCacheObj(ScExternalRefCache::Table* pTable);
++    explicit ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable);
 +    ~ScExternalSheetCacheObj();
 +
 +                            // XExternalSheetCache
@@ -654,7 +737,7 @@
 +    ScExternalSheetCacheObj(const ScExternalSheetCacheObj&);
 +
 +private:
-+    ScExternalRefCache::Table* mpTable;
++    ScExternalRefCache::TableTypeRef mpTable;
 +};
 +
 +// ============================================================================
@@ -670,25 +753,29 @@
 +        SAL_CALL addSheetCache( const ::rtl::OUString& aSheetName ) 
 +            throw (::com::sun::star::uno::RuntimeException);
 +
++    // Attributes
++    virtual sal_Int32 SAL_CALL getTokenIndex()
++            throw (::com::sun::star::uno::RuntimeException);
++
 +private:
 +    ScExternalRefManager*   mpRefMgr;
 +    sal_uInt16              mnFileId;
 +};
 +
 +// ============================================================================
- 
++
 +/** 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 ) 
 +            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,
@@ -714,7 +801,7 @@
 +	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&);
@@ -733,14 +820,14 @@
  #endif
  
 diff --git sc/inc/opcode.hxx sc/inc/opcode.hxx
-index 285104d..b72ebad 100644
+index 285104d..e0940f7 100644
 --- sc/inc/opcode.hxx
 +++ sc/inc/opcode.hxx
 @@ -44,6 +44,7 @@ enum OpCodeEnum
  		ocStop				= SC_OPCODE_STOP,
  		ocExternal			= SC_OPCODE_EXTERNAL,
  		ocName				= SC_OPCODE_NAME,
-+        ocExternalName      = SC_OPCODE_EXTERNAL_NAME,
++        ocExternalRef       = SC_OPCODE_EXTERNAL_REF,
  	// Jump commands
  		ocIf				= SC_OPCODE_IF,
  		ocChose				= SC_OPCODE_CHOSE,
@@ -757,19 +844,21 @@
  
  inline void SingleRefData::InitAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
 diff --git sc/inc/token.hxx sc/inc/token.hxx
-index ded3a94..7e49031 100644
+index ded3a94..bc7e993 100644
 --- sc/inc/token.hxx
 +++ sc/inc/token.hxx
-@@ -64,7 +64,7 @@ enum StackVarEnum
+@@ -64,7 +64,9 @@ enum StackVarEnum
                                          // cell during import, having a double
                                          // and/or string result and a formula
                                          // string to be compiled.
 -
++    svExternalSingleRef,
++    svExternalDoubleRef,
 +    svExternalName,
      svError,                            // error token
      svMissing = 0x70,                   // 0 or ""
      svSep,                              // separator, ocSep, ocOpen, ocClose
-@@ -448,6 +448,69 @@ public:
+@@ -448,6 +450,69 @@ public:
  };
  
  
@@ -853,8 +942,31 @@
      ScToken* AddExternal( const sal_Unicode* pStr );
      /** 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
+--- sc/inc/tokenuno.hxx
++++ sc/inc/tokenuno.hxx
+@@ -38,9 +38,8 @@
+ #include <com/sun/star/beans/XPropertySet.hpp>
+ #include <com/sun/star/sheet/XFormulaParser.hpp>
+ #include <com/sun/star/sheet/XFormulaOpCodeMapper.hpp>
+-#ifndef __com_sun_star_sheet_FormulaOpCodeMapEntry_idl__
+ #include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
+-#endif
++#include <com/sun/star/sheet/ExternalLinkInfo.hpp>
+ #include <cppuhelper/implbase3.hxx>
+ #include <cppuhelper/implbase2.hxx>
+ #include "address.hxx"
+@@ -70,6 +69,7 @@ class ScFormulaParserObj : public ::cppu::WeakImplHelper3<
+ {
+ private:
+     ::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::FormulaOpCodeMapEntry > maOpCodeMapping;
++    ::com::sun::star::uno::Sequence< const ::com::sun::star::sheet::ExternalLinkInfo > maExternalLinks;
+     ScCompiler::OpCodeMapPtr    mxOpCodeMap;
+     ScDocShell*         mpDocShell;
+     ScAddress           maRefPos;
 diff --git sc/inc/unonames.hxx sc/inc/unonames.hxx
-index b2c45ac..51ebf60 100644
+index b2c45ac..18c858b 100644
 --- sc/inc/unonames.hxx
 +++ sc/inc/unonames.hxx
 @@ -47,6 +47,7 @@
@@ -865,8 +977,16 @@
  #define SC_UNO_COLLABELRNG			"ColumnLabelRanges"
  #define SC_UNO_DATABASERNG			"DatabaseRanges"
  #define SC_UNO_NAMEDRANGES			"NamedRanges"
+@@ -604,6 +605,7 @@
+ #define SC_UNO_FORMULACONVENTION    "FormulaConvention"
+ #define SC_UNO_IGNORELEADING        "IgnoreLeadingSpaces"
+ #define SC_UNO_OPCODEMAP            "OpCodeMap"
++#define SC_UNO_EXTERNALLINKS        "ExternalLinks"
+ 
+ // Chart2
+ #define SC_UNONAME_ISHIDDEN         "IsHidden"
 diff --git sc/source/core/data/cell.cxx sc/source/core/data/cell.cxx
-index 1c7ac08..4611515 100644
+index 636f46e..fbd55d5 100644
 --- sc/source/core/data/cell.cxx
 +++ sc/source/core/data/cell.cxx
 @@ -689,7 +689,12 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rNewPos,
@@ -874,7 +994,7 @@
  					  t = pCode->GetNextReferenceOrName() )
  		{
 -			if ( t->GetType() == svIndex )
-+            if ( t->GetOpCode() == ocExternalName )
++            if ( t->GetOpCode() == ocExternalRef )
 +            {
 +                // External name, cell, and area references.
 +                bCompile = true;
@@ -1000,10 +1120,10 @@
  {
      if (pLinkManager)
 diff --git sc/source/core/tool/address.cxx sc/source/core/tool/address.cxx
-index 2cb5dce..e518b27 100644
+index 2cb5dce..4572ccd 100644
 --- sc/source/core/tool/address.cxx
 +++ sc/source/core/tool/address.cxx
-@@ -35,6 +35,7 @@
+@@ -35,12 +35,15 @@
  #include "global.hxx"
  #include "compiler.hxx"
  #include "document.hxx"
@@ -1011,7 +1131,15 @@
  
  #include "globstr.hrc"
  #include <sal/alloca.h>
-@@ -68,6 +69,49 @@ void ScAddress::Details::SetPos ( const ScDocument* pDoc,
+ 
+ #include <com/sun/star/frame/XModel.hpp>
+ #include <com/sun/star/beans/XPropertySet.hpp>
++#include <com/sun/star/sheet/ExternalLinkInfo.hpp>
++#include <com/sun/star/sheet/ExternalLinkType.hpp>
+ #include <sfx2/objsh.hxx>
+ #include <tools/urlobj.hxx>
+ using namespace ::com::sun::star;
+@@ -68,6 +71,49 @@ void ScAddress::Details::SetPos ( const ScDocument* pDoc,
  
  #include <iostream>
  
@@ -1061,7 +1189,7 @@
  static long int
  sal_Unicode_strtol ( const sal_Unicode*  p,
                       const sal_Unicode** pEnd )
-@@ -102,31 +146,18 @@ sal_Unicode_strtol ( const sal_Unicode*  p,
+@@ -102,31 +148,18 @@ sal_Unicode_strtol ( const sal_Unicode*  p,
  // Returns NULL if the string should be a sheet name, but is invalid
  // Returns a pointer to the first character after the sheet name
  static const sal_Unicode *
@@ -1096,7 +1224,7 @@
              return NULL;
      }
      else
-@@ -190,26 +221,7 @@ lcl_XL_ParseSheetRef( const sal_Unicode *start,
+@@ -190,26 +223,7 @@ lcl_XL_ParseSheetRef( const sal_Unicode *start,
          aTabName.Append( start, sal::static_int_cast<xub_StrLen>( p - start ) );
      }
  
@@ -1124,7 +1252,16 @@
      return p;
  }
  
-@@ -227,39 +239,33 @@ lcl_ScRange_Parse_XL_Header( ScRange& r,
+@@ -220,46 +234,71 @@ lcl_ScRange_Parse_XL_Header( ScRange& r,
+                              String& rExternDocName,
+                              String& rStartTabName,
+                              String& rEndTabName,
+-                             USHORT& nFlags )
++                             USHORT& nFlags,
++                             const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks )
+ {
+     const sal_Unicode* startTabs, *start = p;
+ 
      // Is this an external reference ?
      rStartTabName.Erase();
      rEndTabName.Erase();
@@ -1161,14 +1298,44 @@
                  return start;
              rExternDocName.Append( start+1, sal::static_int_cast<xub_StrLen>( p-(start+1) ) );
          }
++        ++p;
  
 -        rExternDocName = ScGlobal::GetAbsDocName( rExternDocName,
 -            pDoc->GetDocumentShell() );
 -        if( *p != ']' )
 -            return start;
 -        p++;
++        // 1-based, sequence starts with an empty element.
++        if (pExternalLinks && pExternalLinks->getLength() > 1)
++        {
++            // A numeric "document name" is an index into the sequence.
++            if (CharClass::isAsciiNumeric( rExternDocName))
++            {
++                sal_Int32 i = rExternDocName.ToInt32();
++                if (i <= 0 || i >= pExternalLinks->getLength())
++                    return start;
++                const sheet::ExternalLinkInfo & rInfo = (*pExternalLinks)[i];
++                switch (rInfo.Type)
++                {
++                    case sheet::ExternalLinkType::DOCUMENT :
++                        {
++                            rtl::OUString aStr;
++                            if (!(rInfo.Data >>= aStr))
++                            {
++                                DBG_ERROR1( "lcl_ScRange_Parse_XL_Header: Data type mismatch for ExternalLinkInfo %d", i);
++                                return start;
++                            }
++                            rExternDocName = aStr;
++                        }
++                        break;
++                    default:
++                        DBG_ERROR2( "lcl_ScRange_Parse_XL_Header: unhandled ExternalLinkType %d for index %d",
++                                rInfo.Type, i);
++                        return start;
++                }
++            }
++        }
 +        rExternDocName = ScGlobal::GetAbsDocName(rExternDocName, pDoc->GetDocumentShell());
-+        ++p;
      }
  
      startTabs = p;
@@ -1177,7 +1344,7 @@
      if( NULL == p )
          return start;       // invalid tab
      if( p != startTabs )
-@@ -267,7 +273,7 @@ lcl_ScRange_Parse_XL_Header( ScRange& r,
+@@ -267,7 +306,7 @@ lcl_ScRange_Parse_XL_Header( ScRange& r,
          nFlags |= SCA_VALID_TAB | SCA_TAB_3D | SCA_TAB_ABSOLUTE;
          if( *p == ':' ) // 3d ref
          {
@@ -1186,7 +1353,7 @@
              if( p == NULL )
                  return start; // invalid tab
              nFlags |= SCA_VALID_TAB2 | SCA_TAB2_3D | SCA_TAB2_ABSOLUTE;
-@@ -289,45 +295,36 @@ lcl_ScRange_Parse_XL_Header( ScRange& r,
+@@ -289,45 +328,36 @@ lcl_ScRange_Parse_XL_Header( ScRange& r,
          // Use the current tab, it needs to be passed in. : r.aEnd.SetTab( .. );
      }
  
@@ -1255,19 +1422,22 @@
  }
  
  
-@@ -427,7 +424,7 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
+@@ -427,7 +457,8 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
                             const sal_Unicode* p,
                             ScDocument* pDoc,
                             const ScAddress::Details& rDetails,
 -                           BOOL bOnlyAcceptSingle )
-+                           BOOL bOnlyAcceptSingle, ScAddress::ExternalInfo* pExtInfo )
++                           BOOL bOnlyAcceptSingle,
++                           ScAddress::ExternalInfo* pExtInfo )
  {
      const sal_Unicode* pTmp = NULL;
      String aExternDocName, aStartTabName, aEndTabName;
-@@ -442,6 +439,18 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
+@@ -441,7 +472,19 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
+     }
  #endif
      p = lcl_ScRange_Parse_XL_Header( r, p, pDoc,
-         aExternDocName, aStartTabName, aEndTabName, nFlags );
+-        aExternDocName, aStartTabName, aEndTabName, nFlags );
++            aExternDocName, aStartTabName, aEndTabName, nFlags, NULL );
 +
 +    if (aExternDocName.Len() > 0)
 +    {
@@ -1283,7 +1453,7 @@
      if( NULL == p )
          return 0;
  
-@@ -480,8 +489,7 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
+@@ -480,8 +523,7 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
              r.aStart.SetCol( 0 );
              r.aEnd.SetCol( MAXCOL );
  
@@ -1293,7 +1463,7 @@
          }
          else if( NULL == (p = lcl_r1c1_get_col( p, rDetails, &r.aStart, &nFlags )))
              goto failed;
-@@ -501,8 +509,7 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
+@@ -501,8 +543,7 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
                  return nFlags;
              }
  
@@ -1303,7 +1473,7 @@
          }
          p = pTmp;
  
-@@ -517,8 +524,7 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
+@@ -517,8 +558,7 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
          }
  
          nFlags |= (nFlags2 << 4);
@@ -1313,7 +1483,7 @@
      }
      else if( *p == 'C' || *p == 'c' )   // full col C#
      {
-@@ -550,8 +556,7 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
+@@ -550,8 +590,7 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r,
          r.aStart.SetRow( 0 );
          r.aEnd.SetRow( MAXROW );
  
@@ -1323,20 +1493,23 @@
      }
  
  failed :
-@@ -604,7 +609,8 @@ static USHORT
+@@ -604,7 +643,9 @@ static USHORT
  lcl_ScRange_Parse_XL_A1( ScRange& r,
                           const sal_Unicode* p,
                           ScDocument* pDoc,
 -                         BOOL bOnlyAcceptSingle )
 +                         BOOL bOnlyAcceptSingle,
-+                         ScAddress::ExternalInfo* pExtInfo )
++                         ScAddress::ExternalInfo* pExtInfo,
++                         const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks )
  {
      const sal_Unicode* tmp1, *tmp2;
      String aExternDocName, aStartTabName, aEndTabName; // for external link table
-@@ -619,6 +625,18 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
+@@ -618,7 +659,19 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
+     }
  #endif
      p = lcl_ScRange_Parse_XL_Header( r, p, pDoc,
-         aExternDocName, aStartTabName, aEndTabName, nFlags );
+-        aExternDocName, aStartTabName, aEndTabName, nFlags );
++        aExternDocName, aStartTabName, aEndTabName, nFlags, pExternalLinks );
 +
 +    if (aExternDocName.Len() > 0)
 +    {
@@ -1352,7 +1525,7 @@
      if( NULL == p )
          return 0;
  
-@@ -640,8 +658,7 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
+@@ -640,8 +693,7 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
              SCA_VALID_COL | SCA_VALID_COL2 |
              SCA_COL_ABSOLUTE | SCA_COL2_ABSOLUTE;
          nFlags |= (nFlags2 << 4);
@@ -1362,7 +1535,7 @@
      }
  
      tmp2 = lcl_a1_get_row( tmp1, &r.aStart, &nFlags );
-@@ -661,8 +678,7 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
+@@ -661,8 +713,7 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
              SCA_VALID_ROW | SCA_VALID_ROW2 |
              SCA_ROW_ABSOLUTE | SCA_ROW2_ABSOLUTE;
          nFlags |= (nFlags2 << 4);
@@ -1372,7 +1545,7 @@
      }
  
      // prepare as if it's a singleton, in case we want to fall back */
-@@ -672,8 +688,7 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
+@@ -672,8 +723,7 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
      if ( bOnlyAcceptSingle )
      {
          if ( *tmp2 == 0 )
@@ -1382,7 +1555,7 @@
          else
          {
              // any trailing invalid character must invalidate the address.
-@@ -692,12 +707,11 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
+@@ -692,12 +742,11 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
      p = tmp2;
      tmp1 = lcl_a1_get_col( p+1, &r.aEnd, &nFlags2 );
      if( !tmp1 ) // strange, but valid singleton
@@ -1398,7 +1571,7 @@
  
      if ( *tmp2 != 0 )
      {
-@@ -708,45 +722,31 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
+@@ -708,45 +757,31 @@ lcl_ScRange_Parse_XL_A1( ScRange& r,
      }
  
      nFlags |= (nFlags2 << 4);
@@ -1457,7 +1630,7 @@
      }
  
      SCCOL   nCol = 0;
-@@ -762,25 +762,11 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
+@@ -762,25 +797,11 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
          if (*p == '$')
              nRes |= SCA_TAB_ABSOLUTE, p++;
  
@@ -1488,7 +1661,7 @@
  
          while (*p)
          {
-@@ -795,35 +781,11 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
+@@ -795,35 +816,11 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
          }
          if( *p++ != '.' )
              nBits = 0;
@@ -1528,7 +1701,7 @@
          }
          else
              nBits = 0;
-@@ -884,16 +846,31 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
+@@ -884,16 +881,31 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
          if( !nBits )
              p = q;
      }
@@ -1552,7 +1725,7 @@
 +                pExtInfo->mnFileId = nFileId;
 +            }
 +    
-+            if (pRefMgr->getSingleRefToken(nFileId, aTab, ScAddress(nCol, nRow, 0), NULL, &nTab))
++            if (pRefMgr->getSingleRefToken(nFileId, aTab, ScAddress(nCol, nRow, 0), NULL, &nTab).get())
 +            {
 +                nRes |= SCA_VALID_TAB;
 +            }
@@ -1566,7 +1739,7 @@
      if ( !(nRes & SCA_VALID_ROW) && (nRes & SCA_VALID_COL)
              && !( (nRes & SCA_TAB_3D) && (nRes & SCA_VALID_TAB)) )
      {   // keine Row, keine Tab, aber Col => DM (...), B (...) o.ae.
-@@ -912,9 +889,8 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
+@@ -912,9 +924,10 @@ lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
  }
  
  static USHORT
@@ -1574,11 +1747,13 @@
 -                      ScDocument* pDoc, ScAddress& rAddr,
 -                      const ScAddress::Details& rDetails )
 +lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAddr,
-+                      const ScAddress::Details& rDetails, ScAddress::ExternalInfo* pExtInfo = NULL )
++                      const ScAddress::Details& rDetails,
++                      ScAddress::ExternalInfo* pExtInfo = NULL,
++                      const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks = NULL )
  {
      if( !*p )
          return 0;
-@@ -924,20 +900,20 @@ lcl_ScAddress_Parse ( BOOL& bExternal, const sal_Unicode* p,
+@@ -924,20 +937,22 @@ lcl_ScAddress_Parse ( BOOL& bExternal, const sal_Unicode* p,
      default :
      case ScAddress::CONV_OOO:
          {
@@ -1587,10 +1762,12 @@
          }
  
      case ScAddress::CONV_XL_A1:
++    case ScAddress::CONV_XL_OOX:
          {
              ScRange r = rAddr;
 -            USHORT nFlags = lcl_ScRange_Parse_XL_A1( r, p, pDoc, TRUE );
-+            USHORT nFlags = lcl_ScRange_Parse_XL_A1( r, p, pDoc, TRUE, pExtInfo );
++            USHORT nFlags = lcl_ScRange_Parse_XL_A1( r, p, pDoc, TRUE, pExtInfo,
++                    (rDetails.eConv == ScAddress::CONV_XL_OOX ? pExternalLinks : NULL) );
              rAddr = r.aStart;
              return nFlags;
          }
@@ -1602,7 +1779,7 @@
              rAddr = r.aStart;
              return nFlags;
          }
-@@ -949,9 +925,8 @@ bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
+@@ -949,9 +964,8 @@ bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
                         SCTAB nDefTab, ScRefAddress& rRefAddress,
                         const ScAddress::Details& rDetails )
  {
@@ -1613,20 +1790,22 @@
      if( nRes & SCA_VALID )
      {
          rRefAddress.Set( aAddr,
-@@ -988,10 +963,9 @@ bool ConvertDoubleRef( ScDocument* pDoc, const String& rRefString, SCTAB nDefTab
+@@ -988,10 +1002,11 @@ bool ConvertDoubleRef( ScDocument* pDoc, const String& rRefString, SCTAB nDefTab
  
  
  USHORT ScAddress::Parse( const String& r, ScDocument* pDoc,
 -                         const Details& rDetails)
-+                         const Details& rDetails, ExternalInfo* pExtInfo )
++                         const Details& rDetails,
++                         ExternalInfo* pExtInfo,
++                         const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks )
  {
 -    BOOL bExternal = FALSE;
 -    return lcl_ScAddress_Parse( bExternal, r.GetBuffer(), pDoc, *this, rDetails );
-+    return lcl_ScAddress_Parse( r.GetBuffer(), pDoc, *this, rDetails, pExtInfo );
++    return lcl_ScAddress_Parse( r.GetBuffer(), pDoc, *this, rDetails, pExtInfo, pExternalLinks );
  }
  
  
-@@ -1060,7 +1034,7 @@ void ScRange::ExtendTo( const ScRange& rRange )
+@@ -1060,7 +1075,7 @@ void ScRange::ExtendTo( const ScRange& rRange )
  }
  
  static USHORT
@@ -1635,7 +1814,7 @@
  {
      USHORT nRes1 = 0, nRes2 = 0;
      xub_StrLen nTmp = 0;
-@@ -1073,13 +1047,12 @@ lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc )
+@@ -1073,13 +1088,12 @@ lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc )
          String aTmp( r );
          sal_Unicode* p = aTmp.GetBufferAccess();
          p[ nPos ] = 0;
@@ -1652,16 +1831,18 @@
                      nRes2 &= ~SCA_VALID_TAB;    // #REF!
                  else
                  {
-@@ -1132,7 +1105,7 @@ lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc )
+@@ -1132,7 +1146,9 @@ lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc )
  }
  
  USHORT ScRange::Parse( const String& r, ScDocument* pDoc,
 -                       const ScAddress::Details& rDetails )
-+                       const ScAddress::Details& rDetails, ScAddress::ExternalInfo* pExtInfo )
++                       const ScAddress::Details& rDetails,
++                       ScAddress::ExternalInfo* pExtInfo,
++                       const uno::Sequence< const sheet::ExternalLinkInfo > * pExternalLinks )
  {
      if ( r.Len() <= 0 )
          return 0;
-@@ -1141,13 +1114,13 @@ USHORT ScRange::Parse( const String& r, ScDocument* pDoc,
+@@ -1141,13 +1157,15 @@ USHORT ScRange::Parse( const String& r, ScDocument* pDoc,
      {
      default :
      case ScAddress::CONV_OOO:
@@ -1670,7 +1851,9 @@
  
      case ScAddress::CONV_XL_A1:
 -        return lcl_ScRange_Parse_XL_A1( *this, r.GetBuffer(), pDoc, FALSE );
-+        return lcl_ScRange_Parse_XL_A1( *this, r.GetBuffer(), pDoc, FALSE, pExtInfo );
++    case ScAddress::CONV_XL_OOX:
++        return lcl_ScRange_Parse_XL_A1( *this, r.GetBuffer(), pDoc, FALSE, pExtInfo,
++                (rDetails.eConv == ScAddress::CONV_XL_OOX ? pExternalLinks : NULL) );
  
      case ScAddress::CONV_XL_R1C1:
 -        return lcl_ScRange_Parse_XL_R1C1( *this, r.GetBuffer(), pDoc, rDetails, FALSE );
@@ -1678,8 +1861,56 @@
      }
  }
  
+@@ -1187,6 +1205,7 @@ USHORT ScRange::ParseCols( const String& rStr, ScDocument* pDoc,
+     default :
+     case ScAddress::CONV_OOO: // No full col refs in OOO yet, assume XL notation
+     case ScAddress::CONV_XL_A1:
++    case ScAddress::CONV_XL_OOX:
+         if (NULL != (p = lcl_a1_get_col( p, &aStart, &ignored ) ) )
+         {
+             if( p[0] == ':')
+@@ -1245,6 +1264,7 @@ USHORT ScRange::ParseRows( const String& rStr, ScDocument* pDoc,
+     default :
+     case ScAddress::CONV_OOO: // No full row refs in OOO yet, assume XL notation
+     case ScAddress::CONV_XL_A1:
++    case ScAddress::CONV_XL_OOX:
+         if (NULL != (p = lcl_a1_get_row( p, &aStart, &ignored ) ) )
+         {
+             if( p[0] == ':')
+@@ -1429,6 +1449,7 @@ void ScAddress::Format( String& r, USHORT nFlags, ScDocument* pDoc,
+ 
+             case CONV_XL_A1:
+             case CONV_XL_R1C1:
++            case CONV_XL_OOX:
+                 if (aDocName.Len() > 0)
+                 {
+                     r += '[';
+@@ -1446,6 +1467,7 @@ void ScAddress::Format( String& r, USHORT nFlags, ScDocument* pDoc,
+     default :
+     case CONV_OOO:
+     case CONV_XL_A1:
++    case CONV_XL_OOX:
+         if( nFlags & SCA_VALID_COL )
+             lcl_a1_append_c ( r, nCol, nFlags & SCA_COL_ABSOLUTE );
+         if( nFlags & SCA_VALID_ROW )
+@@ -1565,6 +1587,7 @@ void ScRange::Format( String& r, USHORT nFlags, ScDocument* pDoc,
+     break;
+ 
+     case ScAddress::CONV_XL_A1:
++    case ScAddress::CONV_XL_OOX:
+         lcl_ScRange_Format_XL_Header( r, *this, nFlags, pDoc, rDetails );
+         if( aStart.Col() == 0 && aEnd.Col() >= MAXCOL )
+         {
+@@ -1688,6 +1711,7 @@ String ScAddress::GetColRowString( bool bAbsolute,
+     default :
+     case ScAddress::CONV_OOO:
+     case ScAddress::CONV_XL_A1:
++    case ScAddress::CONV_XL_OOX:
+     if (bAbsolute)
+         aString.Append( '$' );
+ 
 diff --git sc/source/core/tool/compiler.cxx sc/source/core/tool/compiler.cxx
-index 918332d..d9b0549 100644
+index 918332d..f11442e 100644
 --- sc/source/core/tool/compiler.cxx
 +++ sc/source/core/tool/compiler.cxx
 @@ -74,9 +74,11 @@
@@ -1694,7 +1925,180 @@
  
  #if OSL_DEBUG_LEVEL > 1
  // For some unknown reason the identical dbg_dump utilities in
-@@ -1191,7 +1193,7 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
+@@ -109,7 +111,7 @@ ScCompiler::NonConstOpCodeMapPtr    ScCompiler::mxSymbolsPODF;
+ ScCompiler::NonConstOpCodeMapPtr    ScCompiler::mxSymbolsNative;
+ ScCompiler::NonConstOpCodeMapPtr    ScCompiler::mxSymbolsEnglish;
+ CharClass*                          ScCompiler::pCharClassEnglish = NULL;
+-const ScCompiler::Convention*       ScCompiler::pConventions[ ]   = { NULL, NULL, NULL, NULL };
++const ScCompiler::Convention*       ScCompiler::pConventions[ ]   = { NULL, NULL, NULL, NULL, NULL, NULL };
+ 
+ enum ScanState
+ {
+@@ -680,20 +682,15 @@ void ScCompiler::SetGrammar( const ScGrammar::Grammar eGrammar )
+         xMap = ScCompiler::GetOpCodeMap( ::com::sun::star::sheet::FormulaLanguage::NATIVE);
+         eMyGrammar = xMap->getGrammar();
+     }
+-    SetFormulaLanguage( xMap);
+ 
++    // Save old grammar for call to SetGrammarAndRefConvention().
+     ScGrammar::Grammar eOldGrammar = GetGrammar();
+-    meGrammar = eMyGrammar;     //! SetRefConvention needs the new grammar set!
+-    ScAddress::Convention eConv = ScGrammar::extractRefConvention( eMyGrammar);
+-    if (eConv == ScAddress::CONV_UNSPECIFIED && eOldGrammar == ScGrammar::GRAM_UNSPECIFIED)
+-    {
+-        if (NULL != pDoc)
+-            SetRefConvention( pDoc->GetAddressConvention());
+-        else
+-            SetRefConvention( pConvOOO_A1);
+-    }
+-    else
+-        SetRefConvention( eConv );
++    // This also sets the grammar associated with the map!
++    SetFormulaLanguage( xMap);
++
++    // Override if necessary.
++    if (eMyGrammar != GetGrammar())
++        SetGrammarAndRefConvention( eMyGrammar, eOldGrammar);
+ }
+ 
+ // static
+@@ -737,10 +734,28 @@ 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 )
++{
++    meGrammar = eNewGrammar;    //! SetRefConvention needs the new grammar set!
++    ScAddress::Convention eConv = ScGrammar::extractRefConvention( meGrammar);
++    if (eConv == ScAddress::CONV_UNSPECIFIED && eOldGrammar == ScGrammar::GRAM_UNSPECIFIED)
++    {
++        if (pDoc)
++            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
+             sal_Int32 nOff;
+             OpCode    eOp;
+         } aMap[] = {
+-            { 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::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 }
+         };
+         const size_t nCount = sizeof(aMap)/sizeof(aMap[0]);
+         // Preallocate vector elements.
+@@ -1078,7 +1094,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)
+-            t[33] |= SC_COMPILER_C_ODF_LABEL_OP;
++/* ! */     t[33] |= SC_COMPILER_C_ODF_LABEL_OP;
+ /* " */     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 )
+ /* - */     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;
+-for (i = 48; i < 58; i++)
++
++    for (i = 48; i < 58; i++)
+ /* 0-9 */   t[i] = SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_WORD | SC_COMPILER_C_VALUE | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_VALUE | SC_COMPILER_C_IDENT;
++
+ /* : */     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++)
+ /* > */     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
+-for (i = 65; i < 91; i++)
++
++    for (i = 65; i < 91; i++)
+ /* A-Z */   t[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
++
+     if (ScAddress::CONV_ODF == meConv)
+     {
+ /* [ */     t[91] = SC_COMPILER_C_ODF_LBRACKET;
+@@ -1119,14 +1139,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
+-for (i = 97; i < 123; i++)
++
++    for (i = 97; i < 123; i++)
+ /* a-z */   t[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
++
+ /* { */     t[123] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; // array open
+ /* | */     t[124] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; // array row sep (Should be OOo specific)
+ /* } */     t[125] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; // array close
+ /* ~ */     t[126] = SC_COMPILER_C_CHAR;        // OOo specific
+ /* 127 */   // FREE
+-    if( ScAddress::CONV_XL_A1 == meConv || ScAddress::CONV_XL_R1C1 == meConv )
++
++    if( ScAddress::CONV_XL_A1 == meConv || ScAddress::CONV_XL_R1C1 == meConv || ScAddress::CONV_XL_OOX == meConv )
+     {
+ /*   */     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++)
+ 
+         if( ScAddress::CONV_XL_R1C1 == meConv )
+         {
+-        /* - */     t[45] |= SC_COMPILER_C_IDENT;
+-        /* [ */     t[91] |= SC_COMPILER_C_IDENT;
+-        /* ] */     t[93] |= SC_COMPILER_C_IDENT;
++/* - */     t[45] |= SC_COMPILER_C_IDENT;
++/* [ */     t[91] |= SC_COMPILER_C_IDENT;
++/* ] */     t[93] |= SC_COMPILER_C_IDENT;
++        }
++        if( ScAddress::CONV_XL_OOX == meConv )
++        {
++/* [ */     t[91] |= SC_COMPILER_C_CHAR_IDENT;
++/* ] */     t[93] |= SC_COMPILER_C_IDENT;
+         }
+     }
+ }
+@@ -1191,7 +1219,7 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
                  {
                      rRes.TokenType = KParseType::SINGLE_QUOTE_NAME;
                      rRes.EndPos = nPos+1;
@@ -1703,7 +2107,7 @@
                  }
                  ++nPos;
              }
-@@ -1199,9 +1201,197 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
+@@ -1199,9 +1227,203 @@ static bool lcl_isValidQuotedText( const String& rFormula, xub_StrLen nSrcPos, P
          }
      }
  
@@ -1846,16 +2250,22 @@
 +    return true;
 +}
 +
-+static String lcl_makeExternalNameStr( const String& rFile, const String& rName, const sal_Unicode cSep )
++static String lcl_makeExternalNameStr( const String& rFile, const String& rName,
++        const sal_Unicode cSep, bool bODF )
 +{
-+    String aStr, aFile = rFile;
++    String aFile( rFile);
 +    aFile.SearchAndReplaceAllAscii("'", String::CreateFromAscii("''"));
-+    aStr.Append(sal_Unicode('\''));
-+    aStr.Append(aFile);
-+    aStr.Append(sal_Unicode('\''));
-+    aStr.Append(cSep);
-+    aStr.Append(rName);
-+    return aStr;
++    rtl::OUStringBuffer aBuf( aFile.Len() + rName.Len() + 5);
++    if (bODF)
++        aBuf.append( sal_Unicode( '['));
++    aBuf.append( sal_Unicode( '\''));
++    aBuf.append( aFile);
++    aBuf.append( sal_Unicode( '\''));
++    aBuf.append( cSep);
++    aBuf.append( rName);
++    if (bODF)
++        aBuf.append( sal_Unicode(']'));
++    return String( aBuf.makeStringAndClear());
 +}
 +
 +static bool lcl_getLastTabName( String& rTabName2, const String& rTabName1, 
@@ -1901,7 +2311,7 @@
  struct Convention_A1 : public ScCompiler::Convention
  {
      Convention_A1( ScAddress::Convention eConv ) : ScCompiler::Convention( eConv ) { }
-@@ -1215,14 +1405,14 @@ struct Convention_A1 : public ScCompiler::Convention
+@@ -1215,14 +1437,14 @@ struct Convention_A1 : public ScCompiler::Convention
                                 const CharClass* pCharClass) const
      {
          ParseResult aRet;
@@ -1918,7 +2328,7 @@
          return pCharClass->parseAnyToken( rFormula,
                  nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
      }
-@@ -1405,6 +1595,86 @@ struct ConventionOOO_A1 : public Convention_A1
+@@ -1405,6 +1627,113 @@ struct ConventionOOO_A1 : public Convention_A1
  
          return sal_Unicode(0);
      }
@@ -1930,7 +2340,7 @@
 +
 +    virtual String makeExternalNameStr( const String& rFile, const String& rName ) const
 +    {
-+        return lcl_makeExternalNameStr(rFile, rName, sal_Unicode('#'));
++        return lcl_makeExternalNameStr( rFile, rName, sal_Unicode('#'), false);
 +    }
 +
 +    bool makeExternalSingleRefStr( ::rtl::OUStringBuffer& rBuffer, sal_uInt16 nFileId, 
@@ -1967,45 +2377,98 @@
 +        return true;
 +    }
 +
-+    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
++    void makeExternalRefStrImpl( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
 +                                     sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef, 
-+                                     ScExternalRefManager* pRefMgr ) const
++                                     ScExternalRefManager* pRefMgr, bool bODF ) const
 +    {
 +        SingleRefData aRef(rRef);
 +        aRef.CalcAbsIfRel(rCompiler.GetPos());
 +
++        if (bODF)
++            rBuffer.append( sal_Unicode('['));
 +        makeExternalSingleRefStr(rBuffer, nFileId, rTabName, aRef, pRefMgr, true);
++        if (bODF)
++            rBuffer.append( sal_Unicode(']'));
 +    }
 +
 +    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 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, 
++                                     ScExternalRefManager* pRefMgr, bool bODF ) const
++    {
 +        ComplRefData aRef(rRef);
 +        aRef.CalcAbsIfRel(rCompiler.GetPos());
 +
-+        if (!makeExternalSingleRefStr(rBuffer, nFileId, rTabName, aRef.Ref1, pRefMgr, true))
-+            return;
++        if (bODF)
++            rBuffer.append( sal_Unicode('['));
++        // Ensure that there's always a closing bracket, no premature returns.
++        do
++        {
++            if (!makeExternalSingleRefStr(rBuffer, nFileId, rTabName, aRef.Ref1, pRefMgr, true))
++                break;
 +
-+        rBuffer.append(sal_Unicode(':'));
++            rBuffer.append(sal_Unicode(':'));
 +
-+        // Get the name of the last table.
-+        const vector<String>* pTabNames = pRefMgr->getAllCachedTableNames(nFileId);
-+        if (!pTabNames)
-+            return;
++            // Get the name of the last table.
++            const vector<String>* pTabNames = pRefMgr->getAllCachedTableNames(nFileId);
++            if (!pTabNames)
++                break;
 +
-+        String aLastTabName;
-+        if (!lcl_getLastTabName(aLastTabName, rTabName, *pTabNames, aRef))
-+        {
-+            rBuffer.append(aLastTabName);
-+            return;
-+        }
-+        makeExternalSingleRefStr(rBuffer, nFileId, aLastTabName, aRef.Ref2, pRefMgr, (aRef.Ref1.nTab != aRef.Ref2.nTab));
++            String aLastTabName;
++            if (!lcl_getLastTabName(aLastTabName, rTabName, *pTabNames, aRef))
++            {
++                rBuffer.append(aLastTabName);
++                break;
++            }
++            makeExternalSingleRefStr( rBuffer, nFileId, aLastTabName,
++                    aRef.Ref2, pRefMgr, (aRef.Ref1.nTab != aRef.Ref2.nTab));
++        } while (0);
++        if (bODF)
++            rBuffer.append( sal_Unicode(']'));
++    }
++
++    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
++                                     sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef, 
++                                     ScExternalRefManager* pRefMgr ) const
++    {
++        makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, false);
 +    }
  };
  
  
-@@ -1526,11 +1796,128 @@ struct ConventionXL
+@@ -1423,6 +1752,25 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1
+     {
+         MakeRefStrImpl( rBuffer, rComp, rRef, bSingleRef, true);
+     }
++
++    virtual String makeExternalNameStr( const String& rFile, const String& rName ) const
++    {
++        return lcl_makeExternalNameStr( rFile, rName, sal_Unicode('#'), true);
++    }
++
++    virtual void makeExternalRefStr( ::rtl::OUStringBuffer& rBuffer, const ScCompiler& rCompiler,
++                                     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, 
++                                     ScExternalRefManager* pRefMgr ) const
++    {
++        makeExternalRefStrImpl( rBuffer, rCompiler, nFileId, rTabName, rRef, pRefMgr, true);
++    }
+ };
+ 
+ static const ConventionOOO_A1_ODF ConvOOO_A1_ODF;
+@@ -1526,11 +1874,129 @@ struct ConventionXL
          }
          return sal_Unicode(0);
      }
@@ -2017,7 +2480,7 @@
 +
 +    static String makeExternalNameStr( const String& rFile, const String& rName )
 +    {
-+        return lcl_makeExternalNameStr(rFile, rName, sal_Unicode('!'));
++        return lcl_makeExternalNameStr( rFile, rName, sal_Unicode('!'), false);
 +    }
 +
 +    static void makeExternalDocStr( ::rtl::OUStringBuffer& rBuffer, const String& rFullName )
@@ -2120,6 +2583,7 @@
  struct ConventionXL_A1 : public Convention_A1, public ConventionXL
  {
      ConventionXL_A1() : Convention_A1( ScAddress::CONV_XL_A1 ) { }
++    ConventionXL_A1( ScAddress::Convention eConv ) : Convention_A1( eConv ) { }
 +
 +    void makeSingleCellStr( ::rtl::OUStringBuffer& rBuf, const SingleRefData& rRef ) const
 +    {
@@ -2134,7 +2598,7 @@
      void MakeRefStr( rtl::OUStringBuffer&   rBuf,
                       const ScCompiler&      rComp,
                       const ComplRefData& rRef,
-@@ -1584,22 +1971,11 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1584,22 +2050,11 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
              }
          }
  
@@ -2159,7 +2623,7 @@
          }
      }
  
-@@ -1607,8 +1983,10 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1607,8 +2062,10 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
                                         xub_StrLen nSrcPos,
                                         const CharClass* pCharClass) const
      {
@@ -2171,7 +2635,7 @@
              return aRet;
  
          static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
-@@ -1624,6 +2002,67 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+@@ -1624,11 +2081,82 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
      {
          return ConventionXL::getSpecialSymbol(eSymType);
      }
@@ -2239,7 +2703,22 @@
  };
  
  static const ConventionXL_A1 ConvXL_A1;
-@@ -1733,8 +2172,10 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
+ const ScCompiler::Convention * const ScCompiler::pConvXL_A1 = &ConvXL_A1;
+ 
++
++struct ConventionXL_OOX : public ConventionXL_A1
++{
++    ConventionXL_OOX() : ConventionXL_A1( ScAddress::CONV_XL_OOX ) { }
++};
++
++static const ConventionXL_OOX ConvXL_OOX;
++const ScCompiler::Convention * const ScCompiler::pConvXL_OOX = &ConvXL_OOX;
++
++
+ //-----------------------------------------------------------------------------
+ 
+ static void
+@@ -1733,8 +2261,10 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
                                 xub_StrLen nSrcPos,
                                 const CharClass* pCharClass) const
      {
@@ -2251,7 +2730,7 @@
              return aRet;
  
          static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
-@@ -1751,6 +2192,95 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
+@@ -1751,6 +2281,95 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
      {
          return ConventionXL::getSpecialSymbol(eSymType);
      }
@@ -2347,7 +2826,32 @@
  };
  
  static const ConventionXL_R1C1 ConvXL_R1C1;
-@@ -2208,7 +2738,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+@@ -1817,13 +2436,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());
+ 
+-    switch ( eConv ) {
++    switch ( eConv )
++    {
+         default :
+         case ScAddress::CONV_UNSPECIFIED :
+             break;
+         case ScAddress::CONV_OOO :
+         case ScAddress::CONV_XL_A1 :
+         case ScAddress::CONV_XL_R1C1 :
++        case ScAddress::CONV_XL_OOX :
+             if( bNeedsQuote )
+             {
+                 static const String one_quote = static_cast<sal_Unicode>( '\'' );
+@@ -1859,6 +2480,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;
++        case ScAddress::CONV_XL_OOX :   SetRefConvention( pConvXL_OOX ); break;
+     }
+ }
+ 
+@@ -2208,7 +2830,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
                      static const int kQuote = kInc * 2;
                      static const int kPast = kInc * 3;
                      bool bAddToSymbol = true;
@@ -2356,7 +2860,7 @@
                      {
                          // eat it, no sheet name
                          bAddToSymbol = false;
-@@ -2223,7 +2753,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
+@@ -2223,7 +2845,7 @@ xub_StrLen ScCompiler::NextSymbol(bool bInArray)
                      }
                      else if (nRefInSheetName < kPast)
                      {
@@ -2365,17 +2869,17 @@
                              nRefInSheetName += kDollar;
                          else if ('\'' == c)
                          {
-@@ -2545,7 +3075,8 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
+@@ -2545,7 +3167,8 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
  {
      ScRange aRange( aPos, aPos );
      const ScAddress::Details aDetails( pConv->meConv, aPos );
 -    USHORT nFlags = aRange.Parse( rName, pDoc, aDetails );
 +    ScAddress::ExternalInfo aExtInfo;
-+    USHORT nFlags = aRange.Parse( rName, pDoc, aDetails, &aExtInfo );
++    USHORT nFlags = aRange.Parse( rName, pDoc, aDetails, &aExtInfo, &maExternalLinks );
      if( nFlags & SCA_VALID )
      {
          ScRawToken aToken;
-@@ -2564,7 +3095,14 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
+@@ -2564,7 +3187,14 @@ BOOL ScCompiler::IsDoubleReference( const String& rName )
              aRef.Ref2.SetTabDeleted( TRUE );        // #REF!
          aRef.Ref2.SetFlag3D( ( nFlags & SCA_TAB2_3D ) != 0 );
          aRef.CalcRelFromAbs( aPos );
@@ -2391,17 +2895,17 @@
          pRawToken = aToken.Clone();
      }
  
-@@ -2576,7 +3114,8 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
+@@ -2576,7 +3206,8 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
  {
      ScAddress aAddr( aPos );
      const ScAddress::Details aDetails( pConv->meConv, aPos );
 -    USHORT nFlags = aAddr.Parse( rName, pDoc, aDetails );
 +    ScAddress::ExternalInfo aExtInfo;
-+    USHORT nFlags = aAddr.Parse( rName, pDoc, aDetails, &aExtInfo );
++    USHORT nFlags = aAddr.Parse( rName, pDoc, aDetails, &aExtInfo, &maExternalLinks );
      // 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 +3139,11 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
+@@ -2600,7 +3231,11 @@ BOOL ScCompiler::IsSingleReference( const String& rName )
              nFlags |= SCA_VALID;
          }
          aRef.CalcRelFromAbs( aPos );
@@ -2414,7 +2918,7 @@
          pRawToken = aToken.Clone();
      }
  
-@@ -2708,6 +3251,27 @@ BOOL ScCompiler::IsNamedRange( const String& rUpperName )
+@@ -2708,6 +3343,27 @@ BOOL ScCompiler::IsNamedRange( const String& rUpperName )
          return FALSE;
  }
  
@@ -2442,7 +2946,7 @@
  BOOL ScCompiler::IsDBRange( const String& rName )
  {
      USHORT n;
-@@ -3243,7 +3807,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
+@@ -3243,7 +3899,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
          if (mnPredetectedReference)
          {
              String aStr( cSymbol);
@@ -2451,7 +2955,7 @@
              {
                  /* TODO: it would be nice to generate a #REF! error here, which
                   * would need an ocBad token with additional error value.
-@@ -3306,6 +3870,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
+@@ -3306,6 +3962,7 @@ BOOL ScCompiler::NextNewToken( bool bInArray )
                && !(bAllowBooleans && IsBoolean( aUpper ))
                && !IsValue( aUpper )
                && !IsNamedRange( aUpper )
@@ -2459,11 +2963,23 @@
                && !IsDBRange( aUpper )
                && !IsColRowName( aUpper )
                && !(bMayBeFuncName && IsMacro( aUpper ))
-@@ -3641,6 +4206,66 @@ BOOL ScCompiler::GetToken()
+@@ -3628,9 +4285,9 @@ BOOL ScCompiler::GetToken()
+         else
+         {
+             if ( nWasColRowName >= 2 && pToken->GetOpCode() == ocColRowName )
+-            {   // aus einem ocSpaces ein ocIntersect im RPN machen
++            {   // convert an ocSpaces to ocIntersect in RPN
+                 pToken = new ScByteToken( ocIntersect );
+-                pArr->nIndex--;     // ganz schweinisch..
++                pArr->nIndex--;     // we advanced to the second ocColRowName, step back
+             }
+         }
+     }
+@@ -3641,6 +4298,78 @@ BOOL ScCompiler::GetToken()
      }
      if( pToken->GetOpCode() == ocSubTotal )
          glSubTotal = TRUE;
-+    else if ( pToken->GetOpCode() == ocExternalName )
++    else if ( pToken->GetOpCode() == ocExternalRef )
 +    {
 +        // Handle external single and double references, or names.
 +
@@ -2477,56 +2993,77 @@
 +            case svExternalName:
 +            {
 +                const String& rName = pToken->GetString();
-+                ScTokenArray* pNew = pRefMgr->getRangeNameTokens(pToken->GetIndex(), rName, &aPos);
-+                if (pNew)
++                ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getRangeNameTokens(pToken->GetIndex(), rName, &aPos);
++                if (xNew.get())
 +                {
-+                    PushTokenArray(pNew->Clone(), true);
++                    ScTokenArray* pNew = xNew->Clone();
++                    PushTokenArray(pNew, true);
++                    pNew->Reset();
 +                    return GetToken();
 +                }
 +            }
 +            break;
-+            case svSingleRef:
++            case svExternalSingleRef:
 +            {
 +                SingleRefData aData(pToken->GetSingleRef());
 +                if (aData.IsTabRel())
-+                    // external single reference must have an absolute table reference!
++                {
++                    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);
-+                ScToken* pNew = pRefMgr->getSingleRefToken(pToken->GetIndex(), pToken->GetString(), aAddr, &aPos, NULL);
-+                if (pNew)
++                ScExternalRefCache::TokenRef xNew = pRefMgr->getSingleRefToken(pToken->GetIndex(), pToken->GetString(), aAddr, &aPos, NULL);
++                if (xNew.get())
 +                {
-+                    pToken = pNew->Clone();
++                    pToken = xNew->Clone();
 +                    return true;
 +                }
 +            }
 +            break;
-+            case svDoubleRef:
++            case svExternalDoubleRef:
 +            {
 +                ComplRefData aData(pToken->GetDoubleRef());
 +                if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel())
-+                    // external double reference must have an absolute table reference!
++                {
++                    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);
-+                ScTokenArray* pNew = pRefMgr->getDoubleRefTokens(pToken->GetIndex(), pToken->GetString(), aRange, &aPos);
-+                if (pNew)
++                ScExternalRefCache::TokenArrayRef xNew = pRefMgr->getDoubleRefTokens(pToken->GetIndex(), pToken->GetString(), aRange, &aPos);
++                if (xNew.get())
 +                {
-+                    PushTokenArray(pNew->Clone(), true);
++                    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);
 +    }
      else if( pToken->GetOpCode() == ocName )
      {
          ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( pToken->GetIndex() );
-@@ -5638,111 +6263,140 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
+@@ -3796,7 +4525,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() )
+-                        {   // gleicher Row Bereich
++                        {   // identical row range
+                             SCCOL nTmp = rRange.aStart.Col();
+                             if ( nStartCol < nTmp && nTmp <= nMaxCol )
+                                 nMaxCol = nTmp - 1;
+@@ -5638,111 +6367,140 @@ ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToke
          DBG_ERRORFILE("unknown OpCode");
          rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
      }
@@ -2544,7 +3081,7 @@
 -                AppendString( rBuffer, t->GetString() );
 -            break;
 -        case svSingleRef:
-+        if (eOp == ocExternalName)
++        if (eOp == ocExternalRef)
          {
 -            SingleRefData& rRef = t->GetSingleRef();
 -            ComplRefData aRef;
@@ -2769,7 +3306,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..51611ef 100644
+index a20cbd5..87f45c3 100644
 --- sc/source/core/tool/token.cxx
 +++ sc/source/core/tool/token.cxx
 @@ -54,6 +54,8 @@
@@ -2787,8 +3324,8 @@
  
 +void ScRawToken::SetExternalSingleRef( sal_uInt16 nFileId, const String& rTabName, const SingleRefData& rRef )
 +{
-+    eOp = ocExternalName;
-+    eType = svSingleRef;
++    eOp = ocExternalRef;
++    eType = svExternalSingleRef;
 +    nRefCnt = 0;
 +
 +    extref.nFileId = nFileId;
@@ -2802,8 +3339,8 @@
 +
 +void ScRawToken::SetExternalDoubleRef( sal_uInt16 nFileId, const String& rTabName, const ComplRefData& rRef )
 +{
-+    eOp = ocExternalName;
-+    eType = svDoubleRef;
++    eOp = ocExternalRef;
++    eType = svExternalDoubleRef;
 +    nRefCnt = 0;
 +
 +    extref.nFileId = nFileId;
@@ -2816,7 +3353,7 @@
 +
 +void ScRawToken::SetExternalName( sal_uInt16 nFileId, const String& rName )
 +{
-+    eOp = ocExternalName;
++    eOp = ocExternalRef;
 +    eType = svExternalName;
 +    nRefCnt = 0;
 +
@@ -2835,7 +3372,7 @@
          USHORT n = nOffset;
  
 -        switch( eType )
-+        if (eOp == ocExternalName)
++        if (eOp == ocExternalRef)
          {
 -            case svSep:         break;
 -            case svByte:        n += sizeof(ScRawToken::sbyte); break;
@@ -2853,9 +3390,9 @@
 -                                }
 +            switch (eType)
 +            {
-+                case svSingleRef:
-+                case svDoubleRef:    n += sizeof(extref); break;
-+                case svExternalName: n += sizeof(extname); break;
++                case svExternalSingleRef:
++                case svExternalDoubleRef:    n += sizeof(extref); break;
++                case svExternalName:         n += sizeof(extname); break;
 +            }
 +        }
 +        else
@@ -2880,42 +3417,78 @@
          }
          p = (ScRawToken*) new BYTE[ n ];
          memcpy( p, this, n * sizeof(BYTE) );
-@@ -311,12 +367,22 @@ ScToken* ScRawToken::CreateToken() const
+@@ -297,55 +353,57 @@ ScToken* ScRawToken::CreateToken() const
+     {
+         case svByte :
+             return new ScByteToken( eOp, sbyte.cByte, sbyte.bHasForceArray );
+-        //break;
+         case svDouble :
+             IF_NOT_OPCODE_ERROR( ocPush, ScDoubleToken);
+             return new ScDoubleToken( nValue );
+-        //break;
+         case svString :
+             if (eOp == ocPush)
+                 return new ScStringToken( String( cStr ) );
+             else
+                 return new ScStringOpToken( eOp, String( cStr ) );
+-        //break;
          case svSingleRef :
              if (eOp == ocPush)
                  return new ScSingleRefToken( aRef.Ref1 );
-+            else if (eOp == ocExternalName)
-+            {
-+                String aTabName(extref.cTabName);
-+                return new ScExternalSingleRefToken(extref.nFileId, aTabName, extref.aRef.Ref1);
-+            }
              else
                  return new ScSingleRefOpToken( eOp, aRef.Ref1 );
-         //break;
+-        //break;
          case svDoubleRef :
              if (eOp == ocPush)
                  return new ScDoubleRefToken( aRef );
-+            else if (eOp == ocExternalName)
-+            {
-+                String aTabName(extref.cTabName);
-+                return new ScExternalDoubleRefToken(extref.nFileId, aTabName, extref.aRef);
-+            }
              else
                  return new ScDoubleRefOpToken( eOp, aRef );
-         //break;
-@@ -327,6 +393,11 @@ ScToken* ScRawToken::CreateToken() const
+-        //break;
+         case svMatrix :
+             IF_NOT_OPCODE_ERROR( ocPush, ScMatrixToken);
+             return new ScMatrixToken( pMat );
+-        //break;
          case svIndex :
              return new ScIndexToken( eOp, nIndex );
-         //break;
+-        //break;
++        case svExternalSingleRef:
++            {
++                String aTabName(extref.cTabName);
++                return new ScExternalSingleRefToken(extref.nFileId, aTabName, extref.aRef.Ref1);
++            }
++        case svExternalDoubleRef:
++            {
++                String aTabName(extref.cTabName);
++                return new ScExternalDoubleRefToken(extref.nFileId, aTabName, extref.aRef);
++            }
 +        case svExternalName:
-+        {
-+            String aName(extname.cName);
-+            return new ScExternalNameToken( extname.nFileId, aName );
-+        }
++            {
++                String aName(extname.cName);
++                return new ScExternalNameToken( extname.nFileId, aName );
++            }
          case svJump :
              return new ScJumpToken( eOp, (short*) nJump );
-         //break;
-@@ -478,6 +549,7 @@ BOOL ScToken::IsMatrixFunction() const
+-        //break;
+         case svExternal :
+             return new ScExternalToken( eOp, sbyte.cByte, String( cStr+1 ) );
+-        //break;
+         case svFAP :
+             return new ScFAPToken( eOp, sbyte.cByte, NULL );
+-        //break;
+         case svMissing :
+             IF_NOT_OPCODE_ERROR( ocMissing, ScMissingToken);
+             return new ScMissingToken;
+-        //break;
+         case svSep :
+             return new ScOpToken( eOp, svSep );
+-        //break;
+         case svUnknown :
+             return new ScUnknownToken( eOp );
+-        //break;
+         default:
+             {
+                 DBG_ERROR1( "unknown ScRawToken::CreateToken() type %d", int(GetType()));
+@@ -478,68 +536,58 @@ BOOL ScToken::IsMatrixFunction() const
  
  ScToken* ScToken::Clone() const
  {
@@ -2923,84 +3496,170 @@
      switch ( GetType() )
      {
          case svByte :
-@@ -487,20 +559,24 @@ ScToken* ScToken::Clone() const
+             return new ScByteToken( *static_cast<const ScByteToken*>(this) );
+-        //break;
+         case svDouble :
              return new ScDoubleToken( *static_cast<const ScDoubleToken*>(this) );
-         //break;
+-        //break;
          case svString :
 -            if (GetOpCode() == ocPush)
 +            if (nOp == ocPush)
                  return new ScStringToken( *static_cast<const ScStringToken*>(this) );
              else
                  return new ScStringOpToken( *static_cast<const ScStringOpToken*>(this) );
-         //break;
+-        //break;
          case svSingleRef :
 -            if (GetOpCode() == ocPush)
 +            if (nOp == ocPush)
                  return new ScSingleRefToken( *static_cast<const ScSingleRefToken*>(this) );
-+            else if (nOp == ocExternalName)
-+                return new ScExternalSingleRefToken( *static_cast<const ScExternalSingleRefToken*>(this) );
              else
                  return new ScSingleRefOpToken( *static_cast<const ScSingleRefOpToken*>(this) );
-         //break;
+-        //break;
          case svDoubleRef :
 -            if (GetOpCode() == ocPush)
 +            if (nOp == ocPush)
                  return new ScDoubleRefToken( *static_cast<const ScDoubleRefToken*>(this) );
-+            else if (nOp == ocExternalName)
-+                return new ScExternalDoubleRefToken( *static_cast<const ScExternalDoubleRefToken*>(this) );
              else
                  return new ScDoubleRefOpToken( *static_cast<const ScDoubleRefOpToken*>(this) );
-         //break;
-@@ -522,6 +598,9 @@ ScToken* ScToken::Clone() const
+-        //break;
+         case svMatrix :
+             return new ScMatrixToken( *static_cast<const ScMatrixToken*>(this) );
+-        //break;
+         case svIndex :
+             return new ScIndexToken( *static_cast<const ScIndexToken*>(this) );
+-        //break;
+         case svJump :
+             return new ScJumpToken( *static_cast<const ScJumpToken*>(this) );
+-        //break;
+         case svJumpMatrix :
+             return new ScJumpMatrixToken( *static_cast<const ScJumpMatrixToken*>(this) );
+-        //break;
+         case svRefList :
+             return new ScRefListToken( *static_cast<const ScRefListToken*>(this) );
+-        //break;
          case svExternal :
              return new ScExternalToken( *static_cast<const ScExternalToken*>(this) );
-         //break;
+-        //break;
++        case svExternalSingleRef :
++            return new ScExternalSingleRefToken( *static_cast<const ScExternalSingleRefToken*>(this) );
++        case svExternalDoubleRef :
++            return new ScExternalDoubleRefToken( *static_cast<const ScExternalDoubleRefToken*>(this) );
 +        case svExternalName :
 +            return new ScExternalNameToken( *static_cast<const ScExternalNameToken*>(this) );
-+        //break;
          case svFAP :
              return new ScFAPToken( *static_cast<const ScFAPToken*>(this) );
-         //break;
-@@ -660,6 +739,7 @@ ScTokenRef ScToken::ExtendRangeReference( ScToken & rTok1, ScToken & rTok2,
+-        //break;
+         case svMissing :
+             return new ScMissingToken( *static_cast<const ScMissingToken*>(this) );
+-        //break;
+         case svError :
+             return new ScErrorToken( *static_cast<const ScErrorToken*>(this) );
+-        //break;
+         case svEmptyCell :
+             return new ScEmptyCellToken( *static_cast<const ScEmptyCellToken*>(this) );
+-        //break;
+         case svSep :
+             return new ScOpToken( *static_cast<const ScOpToken*>(this) );
+-        //break;
+         case svUnknown :
+             return new ScUnknownToken( *static_cast<const ScUnknownToken*>(this) );
+-        //break;
+         default:
+             DBG_ERROR1( "unknown ScToken::Clone() type %d", int(GetType()));
+             return new ScUnknownToken( ocBad );
+@@ -655,26 +703,52 @@ ScTokenRef ScToken::ExtendRangeReference( ScToken & rTok1, ScToken & rTok2,
+     // Doing a RangeOp with RefList is probably utter nonsense, but Xcl
+     // supports it, so do we.
+     if (((p1 = &rTok1) == 0) || ((p2 = &rTok2) == 0) ||
+-            ((sv1 = p1->GetType()) != svSingleRef && sv1 != svDoubleRef && sv1 != svRefList) ||
++            ((sv1 = p1->GetType()) != svSingleRef && sv1 != svDoubleRef && sv1 != svRefList &&
++             sv1 != svExternalSingleRef && sv1 != svExternalDoubleRef) ||
+             ((sv2 = p2->GetType()) != svSingleRef && sv2 != svDoubleRef && sv2 != svRefList))
          return NULL;
  
      ScTokenRef xRes;
-+    bool bExternal = rTok1.GetOpCode() == ocExternalName;
-     if (sv1 == svSingleRef && sv2 == svSingleRef)
+-    if (sv1 == svSingleRef && sv2 == svSingleRef)
++    bool bExternal = (sv1 == svExternalSingleRef);
++    if ((sv1 == svSingleRef || bExternal) && sv2 == svSingleRef)
      {
          // Range references like Sheet1.A1:A2 are generalized and built by
-@@ -671,7 +751,10 @@ ScTokenRef ScToken::ExtendRangeReference( ScToken & rTok1, ScToken & rTok2,
+         // first creating a DoubleRef from the first SingleRef, effectively
+         // generating Sheet1.A1:A1, and then extending that with A2 as if
+         // Sheet1.A1:A1:A2 was encountered, so the mechanisms to adjust the
+         // references apply as well.
++
++        /* Given the current structure of external references an external
++         * reference can only be extended if the second reference does not
++         * point to a different sheet. 'file'#Sheet1.A1:A2 is ok,
++         * 'file'#Sheet1.A1:Sheet2.A2 is not. Since we can't determine from a
++         * svSingleRef whether the sheet would be different from the one given
++         * in the external reference, we have to bail out if there is any sheet
++         * specified. NOTE: Xcl does handle external 3D references as in
++         * '[file]Sheet1:Sheet2'!A1:A2
++         *
++         * FIXME: For OOo syntax be smart and remember an external singleref
++         * encountered and if followed by ocRange and singleref, create an
++         * external singleref for the second singleref. Both could then be
++         * merged here. For Xcl syntax already parse an external range
++         * reference entirely, cumbersome. */
++
++        const SingleRefData& rRef2 = p2->GetSingleRef();
++        if (bExternal && rRef2.IsFlag3D())
++            return NULL;
++
+         ComplRefData aRef;
          aRef.Ref1 = aRef.Ref2 = p1->GetSingleRef();
          aRef.Ref2.SetFlag3D( false);
-         aRef.Extend( p2->GetSingleRef(), rPos);
+-        aRef.Extend( p2->GetSingleRef(), rPos);
 -        xRes = new ScDoubleRefToken( aRef);
++        aRef.Extend( rRef2, rPos);
 +        if (bExternal)
-+            xRes = new ScExternalDoubleRefToken(rTok1.GetIndex(), rTok1.GetString(), aRef);
++            xRes = new ScExternalDoubleRefToken( p1->GetIndex(), p1->GetString(), aRef);
 +        else
 +            xRes = new ScDoubleRefToken( aRef);
      }
      else
      {
-@@ -694,7 +777,10 @@ ScTokenRef ScToken::ExtendRangeReference( ScToken & rTok1, ScToken & rTok2,
++        bExternal |= (sv1 == svExternalDoubleRef);
+         const ScRefList* pRefList = NULL;
+         if (sv1 == svDoubleRef)
+         {
+@@ -694,6 +768,8 @@ ScTokenRef ScToken::ExtendRangeReference( ScToken & rTok1, ScToken & rTok2,
          {
              if (!pRefList->size())
                  return NULL;
--            xRes = new ScDoubleRefToken( (*pRefList)[0] );
 +            if (bExternal)
-+                xRes = new ScExternalDoubleRefToken(rTok1.GetIndex(), rTok1.GetString(), (*pRefList)[0]);
-+            else
-+                xRes = new ScDoubleRefToken( (*pRefList)[0] );
++                return NULL;    // external reference list not possible
+             xRes = new ScDoubleRefToken( (*pRefList)[0] );
          }
          if (!xRes)
-             return NULL;    // shouldn't happen..
-@@ -1035,6 +1121,190 @@ BOOL ScIndexToken::operator==( const ScToken& r ) const
+@@ -724,6 +800,18 @@ ScTokenRef ScToken::ExtendRangeReference( ScToken & rTok1, ScToken & rTok2,
+                         }
+                     }
+                     break;
++                case svExternalSingleRef:
++                    if (rRef.Ref1.IsFlag3D() || rRef.Ref2.IsFlag3D())
++                        return NULL;    // no other sheets with external refs
++                    else
++                        rRef.Extend( pt[i]->GetSingleRef(), rPos);
++                    break;
++                case svExternalDoubleRef:
++                    if (rRef.Ref1.IsFlag3D() || rRef.Ref2.IsFlag3D())
++                        return NULL;    // no other sheets with external refs
++                    else
++                        rRef.Extend( pt[i]->GetDoubleRef(), rPos);
++                    break;
+                 default:
+                     ;   // nothing, prevent compiler warning
+             }
+@@ -1035,6 +1123,190 @@ BOOL ScIndexToken::operator==( const ScToken& r ) const
      return ScToken::operator==( r ) && nIndex == r.GetIndex();
  }
  
 +// ============================================================================
 +
 +ScExternalSingleRefToken::ScExternalSingleRefToken( sal_uInt16 nFileId, const String& rTabName, const SingleRefData& r ) :
-+    ScOpToken(ocExternalName, svSingleRef),
++    ScOpToken(ocExternalRef, svExternalSingleRef),
 +    mnFileId(nFileId),
 +    maTabName(rTabName),
 +    maSingleRef(r)
@@ -3056,7 +3715,7 @@
 +// ============================================================================
 +
 +ScExternalDoubleRefToken::ScExternalDoubleRefToken( sal_uInt16 nFileId, const String& rTabName, const ComplRefData& r ) :
-+    ScOpToken(ocExternalName, svDoubleRef),
++    ScOpToken(ocExternalRef, svExternalDoubleRef),
 +    mnFileId(nFileId),
 +    maTabName(rTabName),
 +    maDoubleRef(r)
@@ -3132,7 +3791,7 @@
 +// ============================================================================
 +
 +ScExternalNameToken::ScExternalNameToken( sal_uInt16 nFileId, const String& rName ) :
-+    ScOpToken(ocExternalName, svExternalName),
++    ScOpToken(ocExternalRef, svExternalName),
 +    mnFileId(nFileId),
 +    maName(rName)
 +{
@@ -3184,17 +3843,33 @@
  
  short* ScJumpToken::GetJump() const                     { return pJump; }
  BOOL ScJumpToken::operator==( const ScToken& r ) const
-@@ -1237,6 +1507,9 @@ ScToken* ScTokenArray::GetNextReferenceOrName()
- {
-     for( ScToken* t = Next(); t; t = Next() )
-     {
-+        if ( t->GetOpCode() == ocExternalName )
-+            return t;
-+
-         switch( t->GetType() )
-         {
+@@ -1242,6 +1514,9 @@ ScToken* ScTokenArray::GetNextReferenceOrName()
              case svSingleRef:
-@@ -1893,6 +2166,21 @@ ScToken* ScTokenArray::AddMatrix( ScMatrix* p )
+             case svDoubleRef:
+             case svIndex:
++            case svExternalSingleRef:
++            case svExternalDoubleRef:
++            case svExternalName:
+                 return t;
+             default:
+             {
+@@ -1785,10 +2060,11 @@ ScToken* ScTokenArray::MergeRangeReference( const ScAddress & rPos )
+     if (!pCode || !nLen)
+         return NULL;
+     USHORT nIdx = nLen;
+-    ScToken *p1, *p2, *p3;
+-    if (((p3 = PeekPrev(nIdx)) != 0) && p3->GetType() == svSingleRef &&
+-            ((p2 = PeekPrev(nIdx)) != 0) && p2->GetOpCode() == ocRange &&
+-            ((p1 = PeekPrev(nIdx)) != 0) && p1->GetType() == svSingleRef)
++    ScToken *p1, *p2, *p3;      // ref, ocRange, ref
++    // The actual types are checked in ExtendRangeReference().
++    if (((p3 = PeekPrev(nIdx)) != 0) &&
++            (((p2 = PeekPrev(nIdx)) != 0) && p2->GetOpCode() == ocRange) &&
++            ((p1 = PeekPrev(nIdx)) != 0))
+     {
+         ScTokenRef p = ScToken::ExtendRangeReference( *p1, *p3, rPos, true);
+         if (p)
+@@ -1893,6 +2169,21 @@ ScToken* ScTokenArray::AddMatrix( ScMatrix* p )
      return Add( new ScMatrixToken( p ) );
  }
  
@@ -3816,7 +4491,7 @@
  
  
 diff --git sc/source/filter/excel/xeformula.cxx sc/source/filter/excel/xeformula.cxx
-index 3db8da7..947b4ce 100644
+index 3db8da7..6488f69 100644
 --- sc/source/filter/excel/xeformula.cxx
 +++ sc/source/filter/excel/xeformula.cxx
 @@ -42,6 +42,11 @@
@@ -3876,7 +4551,7 @@
      StackVar eTokType = aTokData.GetType();
      OpCode eOpCode = aTokData.GetOpCode();
  
-+    if (eOpCode == ocExternalName)
++    if (eOpCode == ocExternalRef)
 +    {
 +        ProcessExternalName( aTokData, nExpClass );
 +        return GetNextToken();
@@ -3907,8 +4582,8 @@
 +            SingleRefData aRef(rTokData.mpScToken->GetSingleRef());
 +            aRef.CalcAbsIfRel(*mpScBasePos);
 +            const String& rTabName = rTokData.mpScToken->GetString();
-+            ScToken* p = pRefMgr->getSingleRefToken(nFileId, rTabName, ScAddress(aRef.nCol, aRef.nRow, aRef.nTab), NULL, NULL);
-+            if (!p)
++            ScExternalRefCache::TokenRef p = pRefMgr->getSingleRefToken(nFileId, rTabName, ScAddress(aRef.nCol, aRef.nRow, aRef.nTab), NULL, NULL);
++            if (!p.get())
 +            {
 +                AppendErrorToken(EXC_ERR_REF, rTokData.mnSpaces);
 +                break;
@@ -3946,8 +4621,8 @@
 +            const SingleRefData& r1 = aRef.Ref1;
 +            const SingleRefData& r2 = aRef.Ref2;
 +            ScRange aRange(r1.nCol, r1.nRow, r1.nTab, r2.nCol, r2.nRow, r2.nTab);
-+            ScTokenArray* pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, aRange, NULL);
-+            if (!pArray)
++            ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, aRange, NULL);
++            if (!pArray.get())
 +            {
 +                AppendErrorToken(EXC_ERR_REF, rTokData.mnSpaces);
 +                break;
@@ -3975,8 +4650,8 @@
 +        case svExternalName:
 +        {
 +            const String& aName = rTokData.mpScToken->GetString();
-+            ScTokenArray* pArray = pRefMgr->getRangeNameTokens(nFileId, aName);
-+            if (!pArray || !mpScBasePos)
++            ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getRangeNameTokens(nFileId, aName);
++            if (!pArray.get() || !mpScBasePos)
 +            {    
 +                AppendErrorToken(XclTools::GetXclErrorCode(errNoName), rTokData.mnSpaces);
 +                break;
@@ -3986,15 +4661,15 @@
 +            // references for CRN records.
 +            for (ScToken* p = pArray->First(); p; p = pArray->Next())
 +            {
-+                if (p->GetOpCode() == ocExternalName)
++                if (p->GetOpCode() == ocExternalRef)
 +                {
-+                    if (p->GetType() == svSingleRef)
++                    if (p->GetType() == svExternalSingleRef)
 +                    {
 +                        SingleRefData aData(p->GetSingleRef());
 +                        aData.CalcAbsIfRel(*mpScBasePos);
 +                        mpLinkMgr->StoreCell(nFileId, p->GetString(), aData);
 +                    }
-+                    else if (p->GetType() == svDoubleRef)
++                    else if (p->GetType() == svExternalDoubleRef)
 +                    {
 +                        ComplRefData aData(p->GetDoubleRef());
 +                        aData.CalcAbsIfRel(*mpScBasePos);
@@ -4051,7 +4726,7 @@
  
  SCTAB XclExpFmlaCompImpl::GetScTab( const SingleRefData& rRefData ) const
 diff --git sc/source/filter/excel/xelink.cxx sc/source/filter/excel/xelink.cxx
-index b1bacad..08517ca 100644
+index b1bacad..90217ae 100644
 --- sc/source/filter/excel/xelink.cxx
 +++ sc/source/filter/excel/xelink.cxx
 @@ -38,6 +38,14 @@
@@ -4081,7 +4756,7 @@
 +{
 +public:
 +    explicit            XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook, const String& rName,
-+                                       const ScTokenArray* pArray );
++                                       const ScExternalRefCache::TokenArrayRef pArray );
 +
 +private:
 +    /** Writes additional record contents. */
@@ -4099,7 +4774,7 @@
          @return  The 1-based (Excel-like) list index of the DDE link. */
      sal_uInt16          InsertDde( const String& rApplic, const String& rTopic, const String& rItem );
  
-+    sal_uInt16          InsertExtName( const XclExpSupbook& rSupbook, const String& rName, const ScTokenArray* pArray );
++    sal_uInt16          InsertExtName( const XclExpSupbook& rSupbook, const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
 +
      /** Writes the EXTERNNAME record list. */
      virtual void        Save( XclExpStream& rStrm );
@@ -4131,7 +4806,7 @@
          @return  The 1-based EXTERNNAME record index; or 0, if the record list is full. */
      sal_uInt16          InsertDde( const String& rItem );
  
-+    sal_uInt16          InsertExtName( const String& rName, const ScTokenArray* pArray );
++    sal_uInt16          InsertExtName( const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
 +
      /** Writes the SUPBOOK and all EXTERNNAME, XCT and CRN records. */
      virtual void        Save( XclExpStream& rStrm );
@@ -4152,7 +4827,7 @@
  
 +    bool                InsertExtName(
 +                            sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rUrl,
-+                            const String& rName, const ScTokenArray* pArray );
++                            const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
 +
 +    XclExpXti           GetXti( sal_uInt16 nFileId, const String& rTabName, sal_uInt16 nXclTabSpan,
 +                                XclExpRefLogEntry* pRefLogEntry = NULL );
@@ -4215,7 +4890,7 @@
  
 +    virtual bool        InsertExtName(
 +                            sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
-+                            const String& rName, const ScTokenArray* pArray ) = 0;
++                            const String& rName, const ScExternalRefCache::TokenArrayRef pArray ) = 0;
 +
      /** Derived classes write the entire link table to the passed stream. */
      virtual void        Save( XclExpStream& rStrm ) = 0;
@@ -4243,7 +4918,7 @@
  
 +    virtual bool        InsertExtName(
 +                            sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
-+                            const String& rName, const ScTokenArray* pArray );
++                            const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
 +
      virtual void        Save( XclExpStream& rStrm );
  
@@ -4271,18 +4946,19 @@
  
 +    virtual bool        InsertExtName(
 +                            sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
-+                            const String& rName, const ScTokenArray* pArray );
++                            const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
 +
      virtual void        Save( XclExpStream& rStrm );
  
  private:
-@@ -885,6 +968,100 @@ void XclExpExtNameDde::WriteAddData( XclExpStream& rStrm )
+@@ -885,6 +968,101 @@ void XclExpExtNameDde::WriteAddData( XclExpStream& rStrm )
          mxMatrix->Save( rStrm );
  }
  
 +// ----------------------------------------------------------------------------
 +
-+XclExpExtName::XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook, const String& rName, const ScTokenArray* pArray ) :
++XclExpExtName::XclExpExtName( const XclExpRoot& rRoot, const XclExpSupbook& rSupbook,
++        const String& rName, const ScExternalRefCache::TokenArrayRef pArray ) :
 +    XclExpExtNameBase( rRoot, rName ),
 +    mrSupbook(rSupbook),
 +    mpArray(pArray->Clone())
@@ -4301,12 +4977,12 @@
 +            break;
 +
 +        const ScToken* p = mpArray->First();
-+        if (p->GetOpCode() != ocExternalName)
++        if (p->GetOpCode() != ocExternalRef)
 +            break;
 +
 +        switch (p->GetType())
 +        {
-+            case svSingleRef:
++            case svExternalSingleRef:
 +            {
 +                const SingleRefData& rRef = p->GetSingleRef();
 +                if (rRef.IsTabRel())
@@ -4330,7 +5006,7 @@
 +                rStrm << nSBTab << nSBTab << nRow << nCol;
 +                return;
 +            }
-+            case svDoubleRef:
++            case svExternalDoubleRef:
 +            {
 +                const ComplRefData& rRef = p->GetDoubleRef();
 +                const SingleRefData& r1 = rRef.Ref1;
@@ -4377,11 +5053,12 @@
  // List of external names =====================================================
  
  XclExpExtNameBuffer::XclExpExtNameBuffer( const XclExpRoot& rRoot ) :
-@@ -920,6 +1097,12 @@ sal_uInt16 XclExpExtNameBuffer::InsertDde(
+@@ -920,6 +1098,13 @@ sal_uInt16 XclExpExtNameBuffer::InsertDde(
      return nIndex;
  }
  
-+sal_uInt16 XclExpExtNameBuffer::InsertExtName( const XclExpSupbook& rSupbook, const String& rName, const ScTokenArray* pArray )
++sal_uInt16 XclExpExtNameBuffer::InsertExtName( const XclExpSupbook& rSupbook,
++        const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
 +{
 +    sal_uInt16 nIndex = GetIndex( rName );
 +    return nIndex ? nIndex : AppendNew( new XclExpExtName( GetRoot(), rSupbook, rName, pArray ) );
@@ -4390,7 +5067,7 @@
  void XclExpExtNameBuffer::Save( XclExpStream& rStrm )
  {
      maNameList.Save( rStrm );
-@@ -1066,6 +1249,78 @@ void XclExpXct::StoreCellRange( const XclExpRoot& rRoot, const ScRange& rRange )
+@@ -1066,6 +1251,78 @@ void XclExpXct::StoreCellRange( const XclExpRoot& rRoot, const ScRange& rRange )
      maUsedCells.SetMultiMarkArea( rRange );
  }
  
@@ -4469,7 +5146,7 @@
  void XclExpXct::Save( XclExpStream& rStrm )
  {
      XclExpRecord::Save( rStrm );
-@@ -1168,6 +1423,17 @@ XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl ) :
+@@ -1168,6 +1425,17 @@ XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rUrl ) :
      mnXclTabCount( 0 )
  {
      SetRecSize( 2 + maUrlEncoded.GetSize() );
@@ -4487,7 +5164,7 @@
  }
  
  XclExpSupbook::XclExpSupbook( const XclExpRoot& rRoot, const String& rApplic, const String& rTopic ) :
-@@ -1206,6 +1472,46 @@ void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab )
+@@ -1206,6 +1474,46 @@ void XclExpSupbook::StoreCellRange( const ScRange& rRange, sal_uInt16 nSBTab )
          xXct->StoreCellRange( GetRoot(), rRange );
  }
  
@@ -4534,11 +5211,11 @@
  sal_uInt16 XclExpSupbook::InsertTabName( const String& rTabName )
  {
      DBG_ASSERT( meType == EXC_SBTYPE_EXTERN, "XclExpSupbook::InsertTabName - don't insert sheet names here" );
-@@ -1226,6 +1532,11 @@ sal_uInt16 XclExpSupbook::InsertDde( const String& rItem )
+@@ -1226,6 +1534,11 @@ sal_uInt16 XclExpSupbook::InsertDde( const String& rItem )
      return GetExtNameBuffer().InsertDde( maUrl, maDdeTopic, rItem );
  }
  
-+sal_uInt16 XclExpSupbook::InsertExtName( const String& rName, const ScTokenArray* pArray )
++sal_uInt16 XclExpSupbook::InsertExtName( const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
 +{
 +    return GetExtNameBuffer().InsertExtName(*this, rName, pArray);
 +}
@@ -4546,7 +5223,7 @@
  void XclExpSupbook::Save( XclExpStream& rStrm )
  {
      // SUPBOOK record
-@@ -1289,11 +1600,6 @@ XclExpSupbookBuffer::XclExpSupbookBuffer( const XclExpRoot& rRoot ) :
+@@ -1289,11 +1602,6 @@ XclExpSupbookBuffer::XclExpSupbookBuffer( const XclExpRoot& rRoot ) :
          mnOwnDocSB = Append( xSupbook );
          for( sal_uInt16 nXclTab = 0; nXclTab < nXclCnt; ++nXclTab )
              maSBIndexVec[ nXclTab ].Set( mnOwnDocSB, nXclTab );
@@ -4558,7 +5235,7 @@
      }
  }
  
-@@ -1352,6 +1658,130 @@ void XclExpSupbookBuffer::StoreCellRange( const ScRange& rRange )
+@@ -1352,6 +1660,130 @@ void XclExpSupbookBuffer::StoreCellRange( const ScRange& rRange )
      }
  }
  
@@ -4597,8 +5274,8 @@
 +        nSupbookId = Append(xSupbook);
 +    }
 +
-+    ScToken* pToken = pRefMgr->getSingleRefToken(nFileId, rTabName, rCell, NULL, NULL);
-+    if (!pToken)
++    ScExternalRefCache::TokenRef pToken = pRefMgr->getSingleRefToken(nFileId, rTabName, rCell, NULL, NULL);
++    if (!pToken.get())
 +        return;
 +
 +    sal_uInt16 nSheetId = xSupbook->GetTabIndex(rTabName);
@@ -4642,8 +5319,8 @@
 +    aMatrixList.reserve(nTabCount);
 +
 +    // This is a new'ed instance, so we must manage its life cycle here.
-+    ScTokenArray* pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, rRange, NULL);
-+    if (!pArray)
++    ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(nFileId, rTabName, rRange, NULL);
++    if (!pArray.get())
 +        return;
 +
 +    for (ScToken* p = pArray->First(); p; p = pArray->Next())
@@ -4689,13 +5366,13 @@
  bool XclExpSupbookBuffer::InsertAddIn(
          sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rName )
  {
-@@ -1383,6 +1813,78 @@ bool XclExpSupbookBuffer::InsertDde(
+@@ -1383,6 +1815,78 @@ bool XclExpSupbookBuffer::InsertDde(
      return rnExtName > 0;
  }
  
 +bool XclExpSupbookBuffer::InsertExtName(
 +        sal_uInt16& rnSupbook, sal_uInt16& rnExtName, const String& rUrl,
-+        const String& rName, const ScTokenArray* pArray )
++        const String& rName, const ScExternalRefCache::TokenArrayRef pArray )
 +{
 +    XclExpSupbookRef xSupbook;
 +    if (!GetSupbookUrl(xSupbook, rnSupbook, rUrl))
@@ -4768,7 +5445,7 @@
  void XclExpSupbookBuffer::Save( XclExpStream& rStrm )
  {
      maSupbookList.Save( rStrm );
-@@ -1424,27 +1926,6 @@ sal_uInt16 XclExpSupbookBuffer::Append( XclExpSupbookRef xSupbook )
+@@ -1424,27 +1928,6 @@ sal_uInt16 XclExpSupbookBuffer::Append( XclExpSupbookRef xSupbook )
      return ulimit_cast< sal_uInt16 >( maSupbookList.GetSize() - 1 );
  }
  
@@ -4796,7 +5473,7 @@
  // Export link manager ========================================================
  
  XclExpLinkManagerImpl::XclExpLinkManagerImpl( const XclExpRoot& rRoot ) :
-@@ -1485,11 +1966,29 @@ sal_uInt16 XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode )
+@@ -1485,11 +1968,29 @@ sal_uInt16 XclExpLinkManagerImpl5::FindExtSheet( sal_Unicode cCode )
      return nExtSheet;
  }
  
@@ -4826,13 +5503,13 @@
  bool XclExpLinkManagerImpl5::InsertAddIn(
          sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
  {
-@@ -1510,6 +2009,14 @@ bool XclExpLinkManagerImpl5::InsertDde(
+@@ -1510,6 +2011,14 @@ bool XclExpLinkManagerImpl5::InsertDde(
      return false;
  }
  
 +bool XclExpLinkManagerImpl5::InsertExtName(
 +        sal_uInt16& /*rnExtSheet*/, sal_uInt16& /*rnExtName*/, const String& /*rUrl*/,
-+        const String& /*rName*/, const ScTokenArray* /*pArray*/ )
++        const String& /*rName*/, const ScExternalRefCache::TokenArrayRef /*pArray*/ )
 +{
 +    // not implemented
 +    return false;
@@ -4841,7 +5518,7 @@
  void XclExpLinkManagerImpl5::Save( XclExpStream& rStrm )
  {
      if( sal_uInt16 nExtSheetCount = GetExtSheetCount() )
-@@ -1630,6 +2137,17 @@ sal_uInt16 XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode )
+@@ -1630,6 +2139,17 @@ sal_uInt16 XclExpLinkManagerImpl8::FindExtSheet( sal_Unicode cCode )
      return InsertXti( maSBBuffer.GetXti( EXC_TAB_EXTERNAL, EXC_TAB_EXTERNAL ) );
  }
  
@@ -4859,7 +5536,7 @@
  void XclExpLinkManagerImpl8::StoreCellRange( const SingleRefData& rRef1, const SingleRefData& rRef2 )
  {
      if( !rRef1.IsDeleted() && !rRef2.IsDeleted() && (rRef1.nTab >= 0) && (rRef2.nTab >= 0) )
-@@ -1652,6 +2170,19 @@ void XclExpLinkManagerImpl8::StoreCellRange( const SingleRefData& rRef1, const S
+@@ -1652,6 +2172,19 @@ void XclExpLinkManagerImpl8::StoreCellRange( const SingleRefData& rRef1, const S
      }
  }
  
@@ -4879,12 +5556,12 @@
  bool XclExpLinkManagerImpl8::InsertAddIn(
          sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
  {
-@@ -1677,6 +2208,18 @@ bool XclExpLinkManagerImpl8::InsertDde(
+@@ -1677,6 +2210,18 @@ bool XclExpLinkManagerImpl8::InsertDde(
      return false;
  }
  
-+bool XclExpLinkManagerImpl8::InsertExtName(
-+    sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName, const String& rUrl, const ScTokenArray* pArray )
++bool XclExpLinkManagerImpl8::InsertExtName( sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
++        const String& rName, const String& rUrl, const ScExternalRefCache::TokenArrayRef pArray )
 +{
 +    sal_uInt16 nSupbook;
 +    if( maSBBuffer.InsertExtName( nSupbook, rnExtName, rUrl, rName, pArray ) )
@@ -4898,7 +5575,7 @@
  void XclExpLinkManagerImpl8::Save( XclExpStream& rStrm )
  {
      if( !maXtiVec.empty() )
-@@ -1745,6 +2288,13 @@ sal_uInt16 XclExpLinkManager::FindExtSheet( sal_Unicode cCode )
+@@ -1745,6 +2290,13 @@ sal_uInt16 XclExpLinkManager::FindExtSheet( sal_Unicode cCode )
      return mxImpl->FindExtSheet( cCode );
  }
  
@@ -4912,7 +5589,7 @@
  void XclExpLinkManager::StoreCell( const SingleRefData& rRef )
  {
      mxImpl->StoreCellRange( rRef, rRef );
-@@ -1755,6 +2305,16 @@ void XclExpLinkManager::StoreCellRange( const ComplRefData& rRef )
+@@ -1755,6 +2307,16 @@ void XclExpLinkManager::StoreCellRange( const ComplRefData& rRef )
      mxImpl->StoreCellRange( rRef.Ref1, rRef.Ref2 );
  }
  
@@ -4929,13 +5606,13 @@
  bool XclExpLinkManager::InsertAddIn(
          sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName )
  {
-@@ -1768,6 +2328,13 @@ bool XclExpLinkManager::InsertDde(
+@@ -1768,6 +2330,13 @@ bool XclExpLinkManager::InsertDde(
      return mxImpl->InsertDde( rnExtSheet, rnExtName, rApplic, rTopic, rItem );
  }
  
 +bool XclExpLinkManager::InsertExtName(
 +    sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rName, const String& rUrl,
-+    const ScTokenArray* pArray )
++    const ScExternalRefCache::TokenArrayRef pArray )
 +{
 +    return mxImpl->InsertExtName( rnExtSheet, rnExtName, rUrl, rName, pArray );
 +}
@@ -4944,7 +5621,7 @@
  {
      mxImpl->Save( rStrm );
 diff --git sc/source/filter/excel/xilink.cxx sc/source/filter/excel/xilink.cxx
-index 01932a5..ab4c08b 100644
+index 01932a5..0b79f64 100644
 --- sc/source/filter/excel/xilink.cxx
 +++ sc/source/filter/excel/xilink.cxx
 @@ -38,6 +38,13 @@
@@ -4985,7 +5662,7 @@
 -    void                CreateAndFillTable(
 -                            const XclImpRoot& rRoot, const String& rAbsUrl,
 -                            const String& rFilterName, const String& rFilterOpt );
-+    void                LoadCachedValues(ScExternalRefCache::Table* pCacheTable);
++    void                LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable);
  
  private:
      typedef ScfDelList< XclImpCrn > XclImpCrnList;
@@ -5165,7 +5842,7 @@
  
 -void XclImpSupbookTab::CreateAndFillTable( const XclImpRoot& rRoot,
 -        const String& rAbsUrl, const String& rFilterName, const String& rFilterOpt )
-+void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::Table* pCacheTable)
++void XclImpSupbookTab::LoadCachedValues(ScExternalRefCache::TableTypeRef pCacheTable)
  {
 -    if( mnScTab == SCTAB_INVALID )
 -        if( rRoot.GetDoc().InsertLinkedEmptyTab( mnScTab, rAbsUrl, rFilterName, rFilterOpt, maTabName ) )
@@ -5286,7 +5963,7 @@
 +            return;
 +        
 +        const String& rTabName = pTab->GetTabName();
-+        ScExternalRefCache::Table* pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
++        ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true);
 +        pTab->LoadCachedValues(pCacheTable);
      }
  }
@@ -5619,10 +6296,18 @@
  #endif
  
 diff --git sc/source/filter/inc/xelink.hxx sc/source/filter/inc/xelink.hxx
-index 795219c..ee53c3a 100644
+index 795219c..b12f064 100644
 --- sc/source/filter/inc/xelink.hxx
 +++ sc/source/filter/inc/xelink.hxx
-@@ -173,11 +173,19 @@ public:
+@@ -36,6 +36,7 @@
+ #include "xehelper.hxx"
+ #include "xerecord.hxx"
+ #include "xeformula.hxx"
++#include "externalrefmgr.hxx"
+ 
+ class ScRange;
+ struct SingleRefData;
+@@ -173,11 +174,19 @@ public:
      /** Searches for a special EXTERNSHEET index for the own document. */
      sal_uInt16          FindExtSheet( sal_Unicode cCode );
  
@@ -5642,13 +6327,13 @@
      /** Finds or inserts an EXTERNNAME record for an add-in function name.
          @param rnExtSheet  (out-param) Returns the index of the EXTSHEET structure for the add-in function name.
          @param rnExtName  (out-param) Returns the 1-based EXTERNNAME record index.
-@@ -193,6 +201,10 @@ public:
+@@ -193,6 +202,10 @@ public:
                              sal_uInt16& rnExtSheet, sal_uInt16& rnExtName,
                              const String& rApplic, const String& rTopic, const String& rItem );
  
 +    bool                InsertExtName(
 +                            sal_uInt16& rnExtSheet, sal_uInt16& rnExtName, const String& rUrl,
-+                            const String& rName, const ScTokenArray* pArray );
++                            const String& rName, const ScExternalRefCache::TokenArrayRef pArray );
 +
      /** Writes the entire Link table. */
      virtual void        Save( XclExpStream& rStrm );
@@ -6213,7 +6898,7 @@
  //------------------------------------------------------------------
  
 diff --git sc/source/filter/xml/xmlexprt.cxx sc/source/filter/xml/xmlexprt.cxx
-index 441f463..535ed45 100644
+index 441f463..d724e25 100644
 --- sc/source/filter/xml/xmlexprt.cxx
 +++ sc/source/filter/xml/xmlexprt.cxx
 @@ -68,6 +68,7 @@
@@ -6643,8 +7328,8 @@
 +        for (vector<String>::const_iterator itr = pTabNames->begin(), itrEnd = pTabNames->end();
 +              itr != itrEnd; ++itr)
 +        {
-+            ScExternalRefCache::Table* pTable = pRefMgr->getCacheTable(nFileId, *itr, false);
-+            if (!pTable)
++            ScExternalRefCache::TableTypeRef pTable = pRefMgr->getCacheTable(nFileId, *itr, false);
++            if (!pTable.get())
 +                continue;
 +
 +            OUStringBuffer aBuf;
@@ -6760,9 +7445,9 @@
 +                    }
 +
 +                    // Write out this cell.
-+                    ScToken* pToken = pTable->getCell(nRow, nCol).get();
++                    ScExternalRefCache::TokenRef pToken = pTable->getCell(nRow, nCol);
 +                    OUString aStrVal;
-+                    if (pToken)
++                    if (pToken.get())
 +                    {
 +                        switch(pToken->GetType())
 +                        {
@@ -6824,7 +7509,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..e1d0ebd
+index 0000000..3417206
 --- /dev/null
 +++ sc/source/filter/xml/xmlexternaltabi.cxx
 @@ -0,0 +1,343 @@
@@ -6990,7 +7675,7 @@
 +
 +void ScXMLExternalRefRowContext::EndElement()
 +{
-+    ScExternalRefCache::Table* pTab = mrExternalRefInfo.mpCacheTable;
++    ScExternalRefCache::TableTypeRef pTab = mrExternalRefInfo.mpCacheTable;
 +
 +    for (sal_Int32 i = 1; i < mnRepeatRowCount; ++i)
 +    {
@@ -7504,7 +8189,7 @@
  extern const XMLPropertyMapEntry aXMLScColumnStylesProperties[];
  extern const XMLPropertyMapEntry aXMLScRowStylesProperties[];
 diff --git sc/source/filter/xml/xmltabi.cxx sc/source/filter/xml/xmltabi.cxx
-index 4a0f83e..264901d 100644
+index 4a0f83e..4dd5a55 100644
 --- sc/source/filter/xml/xmltabi.cxx
 +++ sc/source/filter/xml/xmltabi.cxx
 @@ -40,6 +40,7 @@
@@ -7594,7 +8279,7 @@
 +}
 +
 +ScXMLExternalTabData::ScXMLExternalTabData() :
-+    mpCacheTable(NULL), mnRow(0), mnCol(0), mnFileId(0)
++    mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0)
 +{
 +}
 +
@@ -7680,7 +8365,7 @@
  
  	if( !pContext )
 diff --git sc/source/filter/xml/xmltabi.hxx sc/source/filter/xml/xmltabi.hxx
-index 687cff8..e2960c2 100644
+index 687cff8..5dbfeea 100644
 --- sc/source/filter/xml/xmltabi.hxx
 +++ sc/source/filter/xml/xmltabi.hxx
 @@ -30,13 +30,28 @@
@@ -7697,7 +8382,7 @@
 +struct ScXMLExternalTabData
 +{
 +    String maFileUrl;
-+    ScExternalRefCache::Table* mpCacheTable;
++    ScExternalRefCache::TableTypeRef mpCacheTable;
 +    sal_Int32 mnRow;
 +    sal_Int32 mnCol;
 +    sal_uInt16 mnFileId;
@@ -7746,10 +8431,10 @@
  
 diff --git sc/source/ui/docshell/externalrefmgr.cxx sc/source/ui/docshell/externalrefmgr.cxx
 new file mode 100644
-index 0000000..25266aa
+index 0000000..1a06014
 --- /dev/null
 +++ sc/source/ui/docshell/externalrefmgr.cxx
-@@ -0,0 +1,1328 @@
+@@ -0,0 +1,1319 @@
 +/*************************************************************************
 + *
 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -7922,13 +8607,13 @@
 +{
 +}
 +
-+ScToken* ScExternalRefCache::getCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol)
++ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol)
 +{
 +    DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
 +    if (itrDoc == maDocs.end())
 +    {
 +        // specified document is not cached.
-+        return NULL;
++        return TokenRef();
 +    }
 +
 +    const DocItem& rDoc = itrDoc->second;
@@ -7936,36 +8621,36 @@
 +    if (itrTabId == rDoc.maTableNameIndex.end())
 +    {
 +        // the specified table is not in cache.
-+        return NULL;
++        return TokenRef();
 +    }
 +
 +    const TableTypeRef& pTableData = rDoc.maTables[itrTabId->second];
 +    if (!pTableData.get())
 +    {
 +        // the table data is not instantiated yet.
-+        return NULL;
++        return TokenRef();
 +    }
-+    return pTableData->getCell(nRow, nCol).get();
++    return pTableData->getCell(nRow, nCol);
 +}
 +
-+ScTokenArray* ScExternalRefCache::getCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange)
++ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange)
 +{
 +    DocDataType::iterator itrDoc = maDocs.find(nFileId);
 +    if (itrDoc == maDocs.end())
 +        // specified document is not cached.
-+        return NULL;
++        return TokenArrayRef();
 +
 +    DocItem& rDoc = itrDoc->second;
 +    RangeArrayMap::const_iterator itrRange = rDoc.maRangeArrays.find(rRange);
 +    if (itrRange != rDoc.maRangeArrays.end())
 +    {
-+        return itrRange->second.get();
++        return itrRange->second;
 +    }
 +
 +    TableNameIndexMap::iterator itrTabId = rDoc.maTableNameIndex.find(rTabName);
 +    if (itrTabId == rDoc.maTableNameIndex.end())
 +        // the specified table is not in cache.
-+        return NULL;
++        return TokenArrayRef();
 +
 +    const ScAddress& s = rRange.aStart;
 +    const ScAddress& e = rRange.aEnd;
@@ -7979,7 +8664,7 @@
 +    size_t nTabLastId  = nTabFirstId + nTab2 - nTab1;
 +    if (nTabLastId >= rDoc.maTables.size())
 +        // not all tables are cached.
-+        return NULL;
++        return TokenArrayRef();
 +
 +    TokenArrayRef pArray(new ScTokenArray);
 +    bool bFirstTab = true;
@@ -7987,7 +8672,7 @@
 +    {
 +        TableTypeRef pTab = rDoc.maTables[nTab];
 +        if (!pTab.get())
-+            return NULL;
++            return TokenArrayRef();
 +
 +        ScMatrixRef xMat = new ScMatrix(
 +            static_cast<SCSIZE>(nCol2-nCol1+1), static_cast<SCSIZE>(nRow2-nRow1+1));
@@ -7998,7 +8683,7 @@
 +            {
 +                ScToken* pToken = pTab->getCell(nRow, nCol).get();
 +                if (!pToken)
-+                    return NULL;
++                    return TokenArrayRef();
 +
 +                SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
 +                switch (pToken->GetType())
@@ -8025,21 +8710,21 @@
 +        bFirstTab = false;
 +    }
 +    rDoc.maRangeArrays.insert(RangeArrayMap::value_type(rRange, pArray));
-+    return pArray.get();
++    return pArray;
 +}
 +
-+ScTokenArray* ScExternalRefCache::getRangeNameTokens(sal_uInt16 nFileId, const String& rName)
++ScExternalRefCache::TokenArrayRef ScExternalRefCache::getRangeNameTokens(sal_uInt16 nFileId, const String& rName)
 +{
 +    DocItem* pDoc = getDocItem(nFileId);
 +    if (!pDoc)
-+        return NULL;
++        return TokenArrayRef();
 +
 +    RangeNameMap& rMap = pDoc->maRangeNames;
 +    RangeNameMap::const_iterator itr = rMap.find(rName);
 +    if (itr == rMap.end())
-+        return NULL;
++        return TokenArrayRef();
 +
-+    return itr->second.get();
++    return itr->second;
 +}
 +
 +void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray)
@@ -8197,21 +8882,21 @@
 +    return &pDoc->maTableNames;
 +}
 +
-+ScExternalRefCache::Table* ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew)
++ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew)
 +{
 +    DocItem* pDoc = getDocItem(nFileId);
 +    if (!pDoc)
-+        return NULL;
++        return TableTypeRef();
 +
 +    DocItem& rDoc = *pDoc;
 +
 +    size_t nIndex;
 +    if (lcl_getTableDataIndex(rDoc.maTableNameIndex, rTabName, nIndex))
 +        // specified table found.
-+        return rDoc.maTables[nIndex].get();
++        return rDoc.maTables[nIndex];
 +
 +    if (!bCreateNew)
-+        return NULL;
++        return TableTypeRef();
 +
 +    // Specified table doesn't exist yet.  Create one.
 +    TableTypeRef pTab(new Table);
@@ -8219,7 +8904,7 @@
 +    rDoc.maTableNames.push_back(rTabName);
 +    rDoc.maTableNameIndex.insert(
 +        TableNameIndexMap::value_type(rTabName, rDoc.maTables.size()-1));
-+    return pTab.get();
++    return pTab;
 +}
 +
 +void ScExternalRefCache::clearCache(sal_uInt16 nFileId)
@@ -8453,7 +9138,7 @@
 +    clear();
 +}
 +
-+ScExternalRefCache::Table* ScExternalRefManager::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew)
++ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(sal_uInt16 nFileId, const String& rTabName, bool bCreateNew)
 +{
 +    return maRefCache.getCacheTable(nFileId, rTabName, bCreateNew);
 +}
@@ -8464,8 +9149,9 @@
 +    maRefCache.setRangeNameTokens(nFileId, rName, pArray);
 +}
 +
-+ScToken* ScExternalRefManager::getSingleRefToken(sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell,
-+                                                 const ScAddress* pCurPos, SCTAB* pTab)
++ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
++    sal_uInt16 nFileId, const String& rTabName, const ScAddress& rCell,
++    const ScAddress* pCurPos, SCTAB* pTab)
 +{
 +    if (pCurPos)
 +        insertReferencingCell(nFileId, *pCurPos);
@@ -8476,8 +9162,8 @@
 +        *pTab = -1;
 +
 +    // Check if the given table name and the cell position is cached.
-+    ScToken* pToken = maRefCache.getCellData(nFileId, rTabName, rCell.Row(), rCell.Col());
-+    if (pToken)
++    ScExternalRefCache::TokenRef pToken = maRefCache.getCellData(nFileId, rTabName, rCell.Row(), rCell.Col());
++    if (pToken.get())
 +    {
 +        return pToken;
 +    }
@@ -8486,7 +9172,7 @@
 +    ScDocument* pSrcDoc = getSrcDocument(nFileId);
 +    if (!pSrcDoc)
 +    {
-+        return NULL;
++        return ScExternalRefCache::TokenRef();
 +    }
 +
 +    ScBaseCell* pCell = NULL;
@@ -8494,7 +9180,7 @@
 +    if (!pSrcDoc->GetTable(rTabName, nTab))
 +    {
 +        // specified table name doesn't exist in the source document.
-+        return NULL;
++        return ScExternalRefCache::TokenRef();
 +    }
 +
 +    if (pTab)
@@ -8511,10 +9197,10 @@
 +
 +    // Now, insert the token into cache table.
 +    maRefCache.setCellData(nFileId, rTabName, rCell.Row(), rCell.Col(), pTok);
-+    return pTok.get();
++    return pTok;
 +}
 +
-+ScTokenArray* ScExternalRefManager::getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
++ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
 +{
 +    if (pCurPos)
 +        insertReferencingCell(nFileId, *pCurPos);
@@ -8522,18 +9208,18 @@
 +    maybeLinkExternalFile(nFileId);
 +
 +    // Check if the given table name and the cell position is cached.
-+    ScTokenArray* p = maRefCache.getCellRangeData(nFileId, rTabName, rRange);
-+    if (p)
++    ScExternalRefCache::TokenArrayRef p = maRefCache.getCellRangeData(nFileId, rTabName, rRange);
++    if (p.get())
 +        return p;
 +
 +    ScDocument* pSrcDoc = getSrcDocument(nFileId);
 +    if (!pSrcDoc)
-+        return NULL;
++        return ScExternalRefCache::TokenArrayRef();
 +
 +    SCTAB nTab1;
 +    if (!pSrcDoc->GetTable(rTabName, nTab1))
 +        // specified table name doesn't exist in the source document.
-+        return NULL;
++        return ScExternalRefCache::TokenArrayRef();
 +
 +    ScRange aRange(rRange);
 +    SCTAB nTabSpan = aRange.aEnd.Tab() - aRange.aStart.Tab();
@@ -8563,34 +9249,34 @@
 +    // Cache these values.
 +    maRefCache.setCellRangeData(nFileId, rRange, aCacheData, pArray);
 +
-+    return pArray.get();
++    return pArray;
 +}
 +
-+ScTokenArray* ScExternalRefManager::getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos)
++ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos)
 +{
 +    if (pCurPos)
 +        insertReferencingCell(nFileId, *pCurPos);
 +
 +    maybeLinkExternalFile(nFileId);
 +
-+    ScTokenArray* pArray = maRefCache.getRangeNameTokens(nFileId, rName);
-+    if (pArray)
++    ScExternalRefCache::TokenArrayRef pArray = maRefCache.getRangeNameTokens(nFileId, rName);
++    if (pArray.get())
 +        return pArray;
 +
 +    ScDocument* pSrcDoc = getSrcDocument(nFileId);
 +    if (!pSrcDoc)
-+        return NULL;
++        return ScExternalRefCache::TokenArrayRef();
 +
 +    ScRangeName* pExtNames = pSrcDoc->GetRangeName();
 +    String aUpperName = ScGlobal::pCharClass->upper(rName);
 +    USHORT n;
 +    bool bRes = pExtNames->SearchNameUpper(aUpperName, n);
 +    if (!bRes)
-+        return NULL;
++        return ScExternalRefCache::TokenArrayRef();
 +
 +    ScRangeData* pRangeData = (*pExtNames)[n];
 +    if (!pRangeData)
-+        return NULL;
++        return ScExternalRefCache::TokenArrayRef();
 +
 +    // Parse all tokens in this external range data, and replace each absolute 
 +    // reference token with an external reference token, and cache them.  Also
@@ -8634,7 +9320,7 @@
 +    }
 +
 +    maRefCache.setRangeNameTokens(nFileId, rName, pNew);
-+    return pNew.get();
++    return pNew;
 +}
 +
 +void ScExternalRefManager::refreshAllReferencingCells(sal_uInt16 nFileId)
@@ -8854,21 +9540,11 @@
 +
 +    ScFormulaCell* pFC = static_cast<ScFormulaCell*>(pCell);
 +
-+    // Check to make sure the cell really contains ocExternalName.
-+    bool bCompile = false;
-+    ScTokenArray* pCode = pFC->GetCode();
-+    pCode->Reset();
-+    for (ScToken* p = pCode->First(); p; p = pCode->Next())
-+    {
-+        // External names, external cell and range references all have a 
-+        // ocExternalName token.
-+        if (p->GetOpCode() == ocExternalName)
-+        {
-+            bCompile = true;
-+            break;
-+        }
-+    }
-+    if (!bCompile)
++    // Check to make sure the cell really contains ocExternalRef.
++    // External names, external cell and range references all have a
++    // ocExternalRef token.
++    const ScTokenArray* pCode = pFC->GetCode();
++    if (!pCode->HasOpCode( ocExternalRef))
 +        return false;
 +
 +    ScTokenArray* pArray = pFC->GetCode();
@@ -9138,7 +9814,7 @@
  		{
  			aRet <<= uno::Reference<container::XNameAccess>(new ScSheetLinksObj( pDocShell ));
 diff --git sc/source/ui/unoobj/linkuno.cxx sc/source/ui/unoobj/linkuno.cxx
-index 52a5a62..96a074e 100644
+index 52a5a62..7fb3e01 100644
 --- sc/source/ui/unoobj/linkuno.cxx
 +++ sc/source/ui/unoobj/linkuno.cxx
 @@ -48,8 +48,20 @@
@@ -9162,14 +9838,14 @@
  
  //------------------------------------------------------------------------
  
-@@ -1480,4 +1492,223 @@ uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
+@@ -1480,4 +1492,229 @@ uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
      return xLink;
  }
  
 -//------------------------------------------------------------------------
 +// ============================================================================
 +
-+ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::Table* pTable) :
++ScExternalSheetCacheObj::ScExternalSheetCacheObj(ScExternalRefCache::TableTypeRef pTable) :
 +    mpTable(pTable)
 +{
 +}
@@ -9278,11 +9954,17 @@
 +        throw (RuntimeException)
 +{
 +    ScUnoGuard aGuard;
-+    ScExternalRefCache::Table* pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true);
++    ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true);
 +    Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable));
 +    return aSheetCache;
 +}
 +
++sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
++        throw (RuntimeException)
++{
++    return static_cast<sal_Int32>(mnFileId);
++}
++
 +// ============================================================================
 +
 +ScExternalDocLinksObj::ScExternalDocLinksObj(ScDocShell* pDocShell) :
@@ -9387,6 +10069,55 @@
 +    return static_cast<sal_Bool>(!maDocLinks.empty());
 +}
 +
+diff --git sc/source/ui/unoobj/tokenuno.cxx sc/source/ui/unoobj/tokenuno.cxx
+index f16b1c5..f968d7b 100644
+--- sc/source/ui/unoobj/tokenuno.cxx
++++ sc/source/ui/unoobj/tokenuno.cxx
+@@ -123,6 +123,8 @@ void ScFormulaParserObj::SetCompilerFlags( ScCompiler& rCompiler ) const
+         eConv = aConvMap[mnConv];
+ 
+     rCompiler.SetRefConvention( eConv );
++
++    rCompiler.SetExternalLinks( maExternalLinks);
+ }
+ 
+ uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( const rtl::OUString& aFormula )
+@@ -220,6 +222,11 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue(
+         else
+             throw lang::IllegalArgumentException();
+     }
++    else if ( aString.EqualsAscii( SC_UNO_EXTERNALLINKS ) )
++    {
++        if (!(aValue >>= maExternalLinks))
++            throw lang::IllegalArgumentException();
++    }
+     else
+         throw beans::UnknownPropertyException();
+ }
+@@ -253,6 +260,10 @@ uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPr
+     {
+         aRet <<= maOpCodeMapping;
+     }
++    else if ( aString.EqualsAscii( SC_UNO_EXTERNALLINKS ) )
++    {
++        aRet <<= maExternalLinks;
++    }
+     else
+         throw beans::UnknownPropertyException();
+     return aRet;
+@@ -473,7 +484,12 @@ bool ScTokenConversion::ConvertToTokenSequence( uno::Sequence<sheet::FormulaToke
+                     if (!ScRangeToSequence::FillMixedArray( rAPI.Data, rToken.GetMatrix(), true))
+                         rAPI.Data.clear();
+                     break;
++                case svExternalSingleRef:
++                case svExternalDoubleRef:
++                case svExternalName:
++                // FIXME: svExternal... are to be transported via API.
+                 default:
++                    DBG_ERROR1( "ScTokenConversion::ConvertToTokenSequence: unhandled token type SvStackVar %d", rToken.GetType());
+                     rAPI.Data.clear();      // no data
+             }
+         }
 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]