Index: officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
===================================================================
RCS file: /cvs/util/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu,v
retrieving revision 1.14
diff -u -w -p -r1.14 CalcCommands.xcu
--- officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu	15 Mar 2005 12:42:05 -0000	1.14
+++ officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu	28 Nov 2005 19:35:06 -0000
@@ -1418,6 +1418,20 @@
 					<value xml:lang="en-US">R~ight-To-Left</value>
 				</prop>
 			</node>
+			<node oor:name=".uno:SheetUseR1C1" oor:op="replace">
+				<prop oor:name="Label" oor:type="xs:string">
+					<value xml:lang="en-US">Use R1~C1</value>
+					<value xml:lang="cs">Použij R1~C1</value>
+					<value xml:lang="de">R1~C1 verwenden</value>
+					<value xml:lang="es">Usar R1~C1</value>
+					<value xml:lang="fr">Utiliser R1~C1</value>
+					<value xml:lang="it">Utilizza R1~C1</value>
+					<value xml:lang="ja">R1~C1を使用する</value>
+					<value xml:lang="pt-BR">Usar R1~C1</value>
+					<value xml:lang="zh-CN">使用 R1C1(~C)</value>
+					<value xml:lang="zh-TW">使用 R1C1(~C)</value>
+				</prop>
+			</node>
             <node oor:name=".uno:SetAnchorToPage" oor:op="replace">
                 <prop oor:name="Label" oor:type="xs:string">
                     <value xml:lang="de">An der Seite</value>
diff -r -u -p sc/uiconfig/scalc/menubar/menubar.xml sc/uiconfig/scalc/menubar/menubar.xml
--- sc/uiconfig/scalc/menubar/menubar.xml	2006-09-05 23:35:36.000000000 -0400
+++ sc/uiconfig/scalc/menubar/menubar.xml	2006-08-24 10:45:05.000000000 -0400
@@ -213,6 +213,7 @@
                     <menu:menuitem menu:id=".uno:Hide"/>
                     <menu:menuitem menu:id=".uno:Show"/>
                     <menu:menuitem menu:id=".uno:SheetRightToLeft"/>
+                    <menu:menuitem menu:id=".uno:SheetUseR1C1"/>
                 </menu:menupopup>
             </menu:menu>
             <menu:menu menu:id=".uno:MergeCellsMenu">
diff -r -u -p sc/inc/address.hxx sc/inc/address.hxx
--- sc/inc/address.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/address.hxx	2006-09-05 11:36:58.000000000 -0400
@@ -221,6 +221,9 @@ inline bool ValidColRowTab( SCCOL nCol, 
 #define SCA_VALID_ROW       0x0100
 #define SCA_VALID_COL       0x0200
 #define SCA_VALID_TAB       0x0400
+// somewhat cheesy kludge to force the display of the document name even for
+// local references.  Requires TAB_3D to be valid
+#define SCA_FORCE_DOC       0x0800
 #define SCA_VALID_ROW2      0x1000
 #define SCA_VALID_COL2      0x2000
 #define SCA_VALID_TAB2      0x4000
@@ -248,6 +251,36 @@ public:
 
     enum Uninitialized      { UNINITIALIZED };
     enum InitializeInvalid  { INITIALIZE_INVALID };
+    enum Convention	        {
+		CONV_UNSPECIFIED = -1,	/* useful when we want method to chose, must be first */
+
+		/* elements must be sequential and changes should be reflected in ScCompiler::pCharTables */
+		CONV_OOO	 =  0,	/* 'doc'#sheet.A1:sheet2.B2 */
+		CONV_XL_A1,			/* [doc]sheet:sheet2!A1:B2 */
+		CONV_XL_R1C1,		/* [doc]sheet:sheet2!R1C1:R2C2 */
+
+		CONV_LOTUS_A1,		/* external? 3d? A1.B2 <placeholder/> */
+
+		CONV_LAST	/* for loops, must always be last */
+	};
+	struct Details {
+		Convention	eConv;
+		SCROW   	nRow;
+		SCCOL   	nCol;
+		inline Details( Convention eConvP, SCROW nRowP, SCCOL nColP )
+			: eConv( eConvP ), nRow( nRowP ), nCol( nColP )
+			{}
+		inline Details( Convention eConvP, ScAddress const & rAddr )
+			: eConv( eConvP ), nRow( rAddr.Row() ), nCol( rAddr.Col() )
+			{}
+		inline Details( Convention eConvP)
+			: eConv( eConvP ), nRow( 0 ), nCol( 0 )
+			{}
+		/* Use the convention associated with rAddr::Tab() */
+		Details( const ScDocument* pDoc, const ScAddress & rAddr );
+		void SetPos( const ScDocument* pDoc, const ScAddress & rAddr );
+	};
+	static const Details detailsOOOa1;
 
     inline ScAddress() : nRow(0), nCol(0), nTab(0) {}
     inline ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
@@ -278,8 +311,12 @@ public:
     inline void IncTab( SCsTAB n=1 ) { nTab += n; }
     inline void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
     { nColP = nCol; nRowP = nRow; nTabP = nTab; }
-    USHORT Parse( const String&, ScDocument* = NULL );
-    void Format( String&, USHORT = 0, ScDocument* = NULL ) const;
+
+    USHORT Parse( const String&, ScDocument* = NULL,
+				  const Details& rDetails = detailsOOOa1);
+    void Format( String&, USHORT = 0, ScDocument* = NULL,
+				 const Details& rDetails = detailsOOOa1) const;
+
     // The document for the maximum defined sheet number
     bool Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* =NULL );
     inline bool operator==( const ScAddress& r ) const;
@@ -292,8 +329,9 @@ public:
     // moved from ScTripel
     /// "(1,2,3)"
     String GetText() const;
-    /// "A1" or "$A$1"
-    String GetColRowString( bool bAbsolute = FALSE ) const;
+    /// "A1" or "$A$1" or R1C1 or R[1]C[1]
+    String GetColRowString( bool bAbsolute = FALSE,
+							const Details& rDetails = detailsOOOa1) const;
 };
 
 inline void ScAddress::PutInOrder( ScAddress& r )
@@ -402,11 +440,20 @@ public:
     inline bool IsValid() const { return aStart.IsValid() && aEnd.IsValid(); }
     inline bool In( const ScAddress& ) const;   // is Address& in Range?
     inline bool In( const ScRange& ) const;     // is Range& in Range?
-    USHORT Parse( const String&, ScDocument* = NULL );
-    USHORT ParseAny( const String&, ScDocument* = NULL );
+
+    USHORT Parse( const String&, ScDocument* = NULL,
+				  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
+    USHORT ParseAny( const String&, ScDocument* = NULL,
+					 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
+    USHORT ParseCols( const String&, ScDocument* = NULL,
+					 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
+    USHORT ParseRows( const String&, ScDocument* = NULL,
+					 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
+    void Format( String&, USHORT = 0, ScDocument* = NULL,
+				 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 ) const;
+
     inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
         SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
-    void Format( String&, USHORT = 0, ScDocument* = NULL ) const;
     // The document for the maximum defined sheet number
     bool Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* =NULL );
     void Justify();
@@ -563,7 +610,8 @@ public:
     inline  int     operator != ( const ScRefAddress& r ) const
                     { return !(operator==(r)); }
 
-            String  GetRefString( ScDocument* pDoc, SCTAB nActTab) const;
+            String  GetRefString( ScDocument* pDoc, SCTAB nActTab,
+								  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
 };
 
 inline ScRefAddress& ScRefAddress::operator=( const ScRefAddress& rRef )
@@ -620,11 +668,13 @@ template< typename T > void PutInOrder( 
 }
 
 bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
-        SCTAB nDefTab, ScRefAddress& rRefAddress);
+        SCTAB nDefTab, ScRefAddress& rRefAddress,
+		const ScAddress::Details& rDetails = ScAddress::detailsOOOa1);
 
 bool ConvertDoubleRef(ScDocument* pDoc, const String& rRefString,
         SCTAB nDefTab, ScRefAddress& rStartRefAddress,
-        ScRefAddress& rEndRefAddress);
+        ScRefAddress& rEndRefAddress,
+		const ScAddress::Details& rDetails = ScAddress::detailsOOOa1);
 
 /// append alpha representation of column to buffer
 SC_DLLPUBLIC void ColToAlpha( rtl::OUStringBuffer& rBuffer, SCCOL nCol);
diff -r -u -p sc/inc/attrib.hxx sc/inc/attrib.hxx
--- sc/inc/attrib.hxx	2005-09-08 13:23:08.000000000 -0400
+++ sc/inc/attrib.hxx	2006-09-05 11:34:53.000000000 -0400
@@ -225,15 +225,15 @@ private:
 	USHORT	nFlags;
 };
 
-inline ScRangeItem::ScRangeItem( const USHORT nWhich )
-	:	SfxPoolItem( nWhich ), nFlags( SCR_INVALID ) // == ungueltige Area
+inline ScRangeItem::ScRangeItem( const USHORT nWhichP )
+	:	SfxPoolItem( nWhichP ), nFlags( SCR_INVALID ) // == ungueltige Area
 {
 }
 
-inline ScRangeItem::ScRangeItem( const USHORT	nWhich,
+inline ScRangeItem::ScRangeItem( const USHORT	nWhichP,
 								 const ScRange& rRange,
 								 const USHORT	nNew )
-	: SfxPoolItem( nWhich ), aRange( rRange ), nFlags( nNew )
+	: SfxPoolItem( nWhichP ), aRange( rRange ), nFlags( nNew )
 {
 }
 
@@ -281,8 +281,8 @@ public:
 	SCTAB*  pTabArr;
 };
 
-inline ScTableListItem::ScTableListItem( const USHORT nWhich )
-	: SfxPoolItem(nWhich), nCount(0), pTabArr(NULL)
+inline ScTableListItem::ScTableListItem( const USHORT nWhichP )
+	: SfxPoolItem(nWhichP), nCount(0), pTabArr(NULL)
 {}
 
 //----------------------------------------------------------------------------
diff -r -u -p sc/inc/cell.hxx sc/inc/cell.hxx
--- sc/inc/cell.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/cell.hxx	2006-08-24 10:45:04.000000000 -0400
@@ -247,6 +247,7 @@ class ScFormulaCell : public ScBaseCell,
 private:
 	String			aErgString;
 	double			nErgValue;
+	ScAddress::Convention nErgConv;
 	ScTokenArray*	pCode; 					// das neue Token-Array
 	ScDocument*		pDocument;
 	ScMatrix*		pMatrix;				// Pointer auf Ergebnis-Matrix
@@ -293,8 +294,11 @@ public:
 	// leere Zelle, ggf. mit fertigem TokenArray
 	ScFormulaCell( ScDocument*, const ScAddress&, const ScTokenArray* = NULL, BYTE=0 );
 	// mit Formel
-	ScFormulaCell( ScDocument* pDoc, const ScAddress&,
-				   const String& rFormula, BYTE bMatInd = 0 );
+	ScFormulaCell( ScDocument* pDoc, const ScAddress& aPos,
+				   const String& rFormula,
+				   // Use the conv associated with aPos::nTab by default
+				   ScAddress::Convention eConvP = ScAddress::CONV_UNSPECIFIED,
+				   BYTE bMatInd = 0 );
 	// copy-ctor
     // nCopyFlags:  0 := nothing special
     //              0x0001 := readjust 3D references to point to old position even if relative
@@ -307,9 +311,12 @@ public:
 	ScBaseCell*		Clone(ScDocument* pDoc, const ScAddress&,
 							BOOL bNoListening = FALSE ) const;
 
-	void			GetFormula( String& rFormula ) const;
-	void			GetEnglishFormula( String& rFormula, BOOL bCompileXML = FALSE ) const;
-	void			GetEnglishFormula( rtl::OUStringBuffer& rBuffer, BOOL bCompileXML = FALSE ) const;
+	void			GetFormula( String& rFormula,
+								ScAddress::Convention eConv = ScAddress::CONV_OOO) const;
+	void			GetEnglishFormula( String& rFormula, BOOL bCompileXML = FALSE,
+									   ScAddress::Convention eConv = ScAddress::CONV_OOO) const;
+	void			GetEnglishFormula( rtl::OUStringBuffer& rBuffer, BOOL bCompileXML = FALSE,
+									   ScAddress::Convention eConv = ScAddress::CONV_OOO) const;
 
 	void			Save( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const;
 
@@ -321,7 +328,9 @@ public:
 	BOOL			GetDirty() const { return bDirty; }
     BOOL            NeedsListening() const { return bNeedListening; }
     void            SetNeedsListening( BOOL bVar ) { bNeedListening = bVar; }
-	void			Compile(const String& rFormula, BOOL bNoListening = FALSE );
+	void			Compile(const String& rFormula,
+							BOOL bNoListening = FALSE,
+							ScAddress::Convention eConv = ScAddress::CONV_OOO);
 	void			CompileTokenArray( BOOL bNoListening = FALSE );
 	void			CompileXML( ScProgress& rProgress );		// compile temporary string tokens
 	void			CalcAfterLoad();
@@ -408,7 +417,9 @@ public:
 	// fuer die Importfilter!
 	void 			AddRecalcMode( ScRecalcMode );
 	void			SetDouble( double n )					{ nErgValue = n; bIsValue = TRUE; }
-	void			SetString( const String& r ) 			{ aErgString = r; bIsValue = FALSE; }
+	void			SetString( const String& r,
+							   ScAddress::Convention eConv = ScAddress::CONV_OOO)
+						{ aErgString = r; nErgConv = eConv; bIsValue = FALSE; }
 	void			SetErrCode( USHORT n );
 	inline BOOL		IsHyperLinkCell() const { return pCode && pCode->IsHyperLink(); }
 	EditTextObject*		CreateURLObject() ;
diff -r -u -p sc/inc/cellsuno.hxx sc/inc/cellsuno.hxx
--- sc/inc/cellsuno.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/cellsuno.hxx	2006-08-24 11:17:27.000000000 -0400
@@ -874,6 +874,9 @@ public:
 	virtual ::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > SAL_CALL
 							getCellRangeByName( const ::rtl::OUString& aRange )
 								throw(::com::sun::star::uno::RuntimeException);
+	::com::sun::star::uno::Reference< ::com::sun::star::table::XCellRange > 
+							getCellRangeByName( const ::rtl::OUString& aRange,  const ScAddress::Details& rDetails )
+								throw(::com::sun::star::uno::RuntimeException);
 
 							// XPropertySet ueberladen wegen Range-Properties
 	virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
diff -r -u -p sc/inc/column.hxx sc/inc/column.hxx
--- sc/inc/column.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/column.hxx	2006-08-24 10:45:04.000000000 -0400
@@ -264,7 +264,8 @@ public:
 	BOOL		HasEditCells(SCROW nStartRow, SCROW nEndRow, SCROW& rFirst) const;
 
 				//	TRUE = Zahlformat gesetzt
-	BOOL		SetString( SCROW nRow, SCTAB nTab, const String& rString );
+	BOOL		SetString( SCROW nRow, SCTAB nTab, const String& rString,
+						   ScAddress::Convention conv = ScAddress::CONV_OOO );
 	void		SetValue( SCROW nRow, const double& rVal);
 	void		SetNote( SCROW nRow, const ScPostIt& rNote );
 	void		SetError( SCROW nRow, const USHORT nError);
diff -r -u -p sc/inc/compiler.hrc sc/inc/compiler.hrc
--- sc/inc/compiler.hrc	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/compiler.hrc	2006-08-24 10:46:26.000000000 -0400
@@ -363,9 +363,11 @@
 #define	SC_OPCODE_ISPMT				386
 #define	SC_OPCODE_HYPERLINK			387
 #define SC_OPCODE_GET_PIVOT_DATA	388
-#define	SC_OPCODE_END_2_PAR			389
+#define	SC_OPCODE_INDIRECT_XL		389		/* See also INDIRECT for OOO variant */
+#define	SC_OPCODE_ADRESS_XL		    390		/* See also ADRESS for OOO variant */
+#define	SC_OPCODE_END_2_PAR			391
 
-#define SC_OPCODE_LAST_OPCODE_ID    388      /* letzter OpCode */
+#define SC_OPCODE_LAST_OPCODE_ID    390      /* letzter OpCode */
 
 /*** Interna ***/
 #define	SC_OPCODE_INTERNAL_BEGIN   9995
diff -r -u -p sc/inc/compiler.hxx sc/inc/compiler.hxx
--- sc/inc/compiler.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/compiler.hxx	2006-08-24 10:45:04.000000000 -0400
@@ -223,20 +223,41 @@ struct ScStringHashCode
 };
 typedef ::std::hash_map< String, OpCode, ScStringHashCode, ::std::equal_to< String > > ScOpCodeHashMap;
 
+using namespace ::com::sun::star::i18n;
 class ScCompiler
 {
 public:
+	struct Convention
+	{
+		const ScAddress::Convention meConv;
+		const ULONG*   				mpCharTable;
+
+
+		Convention( ScAddress::Convention eConvP );
+		~Convention();
+
+		virtual void MakeRefStr( rtl::OUStringBuffer&	rBuffer,
+								 const ScCompiler&		rCompiler,
+								 const ComplRefData&	rRef,
+								 BOOL bSingleRef ) const = 0;
+		virtual ::com::sun::star::i18n::ParseResult
+					parseAnyToken( const String& rFormula,
+								   xub_StrLen nSrcPos,
+								   const CharClass* pCharClass) const = 0;
+	};
+
 	static String*	pSymbolTableNative;				// array of native symbols, offset==OpCode
 	static String*	pSymbolTableEnglish; 			// array of English symbols, offset==OpCode
 	static USHORT	nAnzStrings;					// count of symbols
     static ScOpCodeHashMap* pSymbolHashMapNative;   // hash map of native symbols
     static ScOpCodeHashMap* pSymbolHashMapEnglish;  // hash map of English symbols
     static CharClass* pCharClassEnglish;            // character classification for en_US locale
-private:
-    static ULONG*   pCharTable;						// array of ASCII character flags
+	static const Convention *pConventions[ ScAddress::CONV_LAST ];
+
 	ScDocument*	pDoc;
 	ScAddress	aPos;
-	String      cFormula;							// String -> TokenArray
+
+private:
 	String		aCorrectedFormula;					// autocorrected Formula
 	String		aCorrectedSymbol;					// autocorrected Symbol
 	sal_Unicode	cSymbol[MAXSTRLEN];					// current Symbol
@@ -263,7 +284,7 @@ private:
 											// will not be resolved
 	BOOL		bIgnoreErrors;				// on AutoCorrect and CompileForFAP
 											// ignore errors and create RPN nevertheless
-	BOOL		bCompileXML;
+	const Convention *pConv;
 	BOOL		bImportXML;
 
 	BOOL   GetToken();
@@ -282,14 +303,6 @@ private:
 	void NotLine();
 	OpCode Expression();
 
-	String MakeColStr( SCCOL nCol );
-	void MakeColStr( rtl::OUStringBuffer& rBuffer, SCCOL nCol );
-	String MakeRowStr( SCROW nRow );
-	void MakeRowStr( rtl::OUStringBuffer& rBuffer, SCROW nRow );
-	String MakeTabStr( SCTAB nTab, String& aDoc );
-	String MakeRefStr( ComplRefData& rRefData, BOOL bSingleRef );
-	void MakeRefStr( rtl::OUStringBuffer& rBuffer, ComplRefData& rRefData, BOOL bSingleRef );
-
 	void SetError(USHORT nError);
 	xub_StrLen NextSymbol();
 	BOOL IsValue( const String& );
@@ -315,13 +328,15 @@ public:
 
 	static void Init();
 	static void DeInit();
-	static void CheckTabQuotes( String& );	// for ScAddress::Format()
 
-    // Put quotes around string if non-alphanumeric characters are contained,
-    // quote characters contained within are escaped by '\\'.
-	static BOOL EnQuote( String& );
-	// Remove quotes, escaped quotes are unescaped.
-	static BOOL DeQuote( String& );
+	// for ScAddress::Format()
+	static void CheckTabQuotes( String& aTabName,
+								const ScAddress::Convention eConv = ScAddress::CONV_OOO );
+
+	static BOOL EnQuote( String& rStr, 
+						 const ScAddress::Convention eConv = ScAddress::CONV_OOO );
+	static BOOL DeQuote( String& rStr,
+						 const ScAddress::Convention eConv = ScAddress::CONV_OOO );
 
 	//! _either_ CompileForFAP _or_ AutoCorrection, _not_ both
 	void			SetCompileForFAP( BOOL bVal )
@@ -329,13 +344,18 @@ public:
 	void 			SetAutoCorrection( BOOL bVal )
 						{ bAutoCorrect = bVal; bIgnoreErrors = bVal; }
 	void			SetCompileEnglish( BOOL bVal );		// use English SymbolTable
-	void			SetCompileXML( BOOL bVal )
-						{ bCompileXML = bVal; }
+	void			SetRefConvention( const Convention *pConvP );
+	void			SetRefConvention( const ScAddress::Convention eConv );
+
+	void			SetCompileXML( BOOL bVal );	// Deprecate and move to an address conv
 	void			SetImportXML( BOOL bVal )
 						{ bImportXML = bVal; }
 	BOOL			IsCorrected() { return bCorrected; }
 	const String&	GetCorrectedFormula() { return aCorrectedFormula; }
-	ScTokenArray* CompileString( const String& rFormula );
+
+	// Use convention from this->aPos by default
+	ScTokenArray* CompileString( const String& rFormula,
+								 ScAddress::Convention eConv = ScAddress::CONV_UNSPECIFIED );
 	BOOL  CompileTokenArray();
 	short GetNumFormatType() { return nNumFmt; }
 
@@ -374,30 +394,29 @@ public:
 
 	BOOL HasModifiedRange();
 
-	/// Is the CharTable initialized? If not call Init() yourself!
-	static inline BOOL HasCharTable() { return pCharTable != NULL; }
-
-	/// Access the CharTable flags
-	static inline ULONG GetCharTableFlags( sal_Unicode c )
-		{ return c < 128 ? pCharTable[ UINT8(c) ] : 0; }
-
 	/// If the character is allowed as first character in sheet names or references
-	static inline BOOL IsCharWordChar( sal_Unicode c )
+	static inline BOOL IsCharWordChar( sal_Unicode c,
+									   const ScAddress::Convention eConv = ScAddress::CONV_OOO )
 		{
 			return c < 128 ?
-				((pCharTable[ UINT8(c) ] & SC_COMPILER_C_CHAR_WORD) == SC_COMPILER_C_CHAR_WORD) :
+				((pConventions[eConv]->mpCharTable[ UINT8(c) ] & SC_COMPILER_C_CHAR_WORD) == SC_COMPILER_C_CHAR_WORD) :
 				ScGlobal::pCharClass->isLetterNumeric( c );
 		}
 
 	/// If the character is allowed in sheet names or references
-	static inline BOOL IsWordChar( sal_Unicode c )
+	static inline BOOL IsWordChar( sal_Unicode c,
+								   const ScAddress::Convention eConv = ScAddress::CONV_OOO )
 		{
 			return c < 128 ?
-				((pCharTable[ UINT8(c) ] & SC_COMPILER_C_WORD) == SC_COMPILER_C_WORD) :
+				((pConventions[eConv]->mpCharTable[ UINT8(c) ] & SC_COMPILER_C_WORD) == SC_COMPILER_C_WORD) :
 				ScGlobal::pCharClass->isLetterNumeric( c );
 		}
 
 private:
+	/// Access the CharTable flags
+	inline ULONG GetCharTableFlags( sal_Unicode c )
+		{ return c < 128 ? pConv->mpCharTable[ UINT8(c) ] : 0; }
+
     static inline void ForceArrayOperator( ScTokenRef& rCurr, const ScTokenRef& rPrev )
         {
             if ( rPrev.Is() && rPrev->HasForceArray() &&
diff -r -u -p sc/inc/document.hxx sc/inc/document.hxx
--- sc/inc/document.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/document.hxx	2006-08-24 10:45:04.000000000 -0400
@@ -401,6 +401,7 @@ private:
 
 	BOOL				bInUnoBroadcast;
 	BOOL				bInUnoListenerCall;
+	ScAddress::Convention eAddrConv;
 
     mutable BOOL        bStyleSheetUsageInvalid;
 
@@ -583,6 +584,8 @@ SC_DLLPUBLIC	ScDBCollection*	GetDBCollec
 	void			GetScenarioFlags( SCTAB nTab, USHORT& rFlags ) const;
 	BOOL			IsActiveScenario( SCTAB nTab ) const;
 	void			SetActiveScenario( SCTAB nTab, BOOL bActive );		// nur fuer Undo etc.
+	ScAddress::Convention GetAddressConvention() const;
+	void	 	    SetAddressConvention( ScAddress::Convention eConv );
 	BYTE			GetLinkMode( SCTAB nTab ) const;
 	BOOL			IsLinked( SCTAB nTab ) const;
 	const String&	GetLinkDoc( SCTAB nTab ) const;
diff -r -u -p sc/inc/globstr.hrc sc/inc/globstr.hrc
--- sc/inc/globstr.hrc	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/globstr.hrc	2006-08-24 10:45:04.000000000 -0400
@@ -558,7 +558,9 @@
 #define STR_RECALC_MANUAL           416
 #define STR_RECALC_AUTO             417
 
-#define STR_COUNT                   418
+#define STR_UNDO_TAB_R1C1           418
+
+#define STR_COUNT                   419
 
 #endif
 
diff -r -u -p sc/inc/opcode.hxx sc/inc/opcode.hxx
--- sc/inc/opcode.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/opcode.hxx	2006-08-24 10:45:04.000000000 -0400
@@ -268,7 +268,9 @@ enum OpCodeEnum
 		ocDBVarP			= SC_OPCODE_DB_VAR_P,
 	// Verwaltungsfunktionen
 		ocIndirect			= SC_OPCODE_INDIRECT,
+		ocIndirectXL		= SC_OPCODE_INDIRECT_XL,
 		ocAdress			= SC_OPCODE_ADRESS,
+		ocAdressXL			= SC_OPCODE_ADRESS_XL,
 		ocMatch				= SC_OPCODE_MATCH,
 		ocCountEmptyCells	= SC_OPCODE_COUNT_EMPTY_CELLS,
 		ocCountIf			= SC_OPCODE_COUNT_IF,
diff -r -u -p sc/inc/rangelst.hxx sc/inc/rangelst.hxx
--- sc/inc/rangelst.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/rangelst.hxx	2006-09-05 12:50:56.000000000 -0400
@@ -66,8 +66,12 @@ public:
 						Insert( pR, LIST_APPEND );
 					}
 	USHORT			Parse( const String&, ScDocument* = NULL,
-							USHORT nMask = SCA_VALID );
-	void 			Format( String&, USHORT nFlags = 0, ScDocument* = NULL ) const;
+						   USHORT nMask = SCA_VALID,
+						   ScAddress::Convention eConv = ScAddress::CONV_OOO,
+						   char cDelimiter = ';' );
+	void 			Format( String&, USHORT nFlags = 0, ScDocument* = NULL,
+							ScAddress::Convention eConv = ScAddress::CONV_OOO,
+							char cDelimiter = ';') const;
 	void			Join( const ScRange&, BOOL bIsInList = FALSE );
 	BOOL 			UpdateReference( UpdateRefMode, ScDocument*,
 									const ScRange& rWhere,
diff -r -u -p sc/inc/rangenam.hxx sc/inc/rangenam.hxx
--- sc/inc/rangenam.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/rangenam.hxx	2006-08-24 10:45:04.000000000 -0400
@@ -207,8 +207,8 @@ public:
 
 	ScRangeName(const ScRangeName& rScRangeName, ScDocument* pDocument);
 
-	virtual	DataObject* 	Clone(ScDocument* pDoc) const
-							 { return new ScRangeName(*this, pDoc); }
+	virtual	DataObject* 	Clone(ScDocument* pDocP ) const
+							 { return new ScRangeName(*this, pDocP ); }
 	ScRangeData*			operator[]( const USHORT nIndex) const
 							 { return (ScRangeData*)At(nIndex); }
 	virtual	short			Compare(DataObject* pKey1, DataObject* pKey2) const;
diff -r -u -p sc/inc/rangeutl.hxx sc/inc/rangeutl.hxx
--- sc/inc/rangeutl.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/rangeutl.hxx	2006-08-24 10:45:04.000000000 -0400
@@ -71,7 +71,8 @@ public:
 	BOOL	MakeArea			( const String&		rAreaStr,
 								  ScArea&			rArea,
 								  ScDocument*		pDoc,
-								  SCTAB			nTab ) const;
+								  SCTAB			nTab,
+								  ScAddress::Details const & rDetails = ScAddress::detailsOOOa1 ) const;
 
 	void	CutPosString		( const String&		theAreaStr,
 								  String&			thePosStr ) const;
@@ -80,14 +81,16 @@ public:
 								  ScDocument*		pDoc,
 								  ScArea***			pppAreas 	= 0,
 								  USHORT*			pAreaCount	= 0,
-								  BOOL				bAcceptCellRef = FALSE ) const;
+								  BOOL				bAcceptCellRef = FALSE,
+								  ScAddress::Details const & rDetails = ScAddress::detailsOOOa1 ) const;
 
 	BOOL	IsAbsArea			( const String& rAreaStr,
 								  ScDocument*	pDoc,
 								  SCTAB		nTab,
 								  String*		pCompleteStr = 0,
 								  ScRefAddress*	pStartPos	 = 0,
-								  ScRefAddress*	pEndPos		 = 0 ) const;
+								  ScRefAddress*	pEndPos		 = 0,
+								  ScAddress::Details const & rDetails = ScAddress::detailsOOOa1 ) const;
 
 	BOOL	IsRefArea			( const String& rAreaStr,
 								  ScDocument*	pDoc,
@@ -100,14 +103,15 @@ public:
 								  ScDocument*	pDoc,
 								  SCTAB		nTab,
 								  String*		pCompleteStr = 0,
-								  ScRefAddress*	pPosTripel	 = 0 ) const;
+								  ScRefAddress*	pPosTripel	 = 0,
+								  ScAddress::Details const & rDetails = ScAddress::detailsOOOa1 ) const;
 
 	BOOL	MakeRangeFromName	( const String&	rName,
 									ScDocument*		pDoc,
 									SCTAB			nCurTab,
 									ScRange&		rRange,
-									RutlNameScope eScope=RUTL_NAMES
-								  ) const;
+								  RutlNameScope eScope=RUTL_NAMES,
+								  ScAddress::Details const & rDetails = ScAddress::detailsOOOa1 ) const;
 };
 
 //------------------------------------------------------------------------
@@ -128,7 +132,8 @@ public:
 	BOOL	operator==	( const ScArea& r ) const;
 	BOOL	operator!=	( const ScArea& r ) const  { return !( operator==(r) ); }
 	void	GetString	( String& rStr,
-						  BOOL bAbsolute = TRUE, ScDocument* pDoc = NULL ) const;
+						  BOOL bAbsolute = TRUE, ScDocument* pDoc = NULL,
+						  ScAddress::Details const & rDetails = ScAddress::detailsOOOa1 ) const;
 
 public:
 	SCTAB nTab;
diff -r -u -p sc/inc/reffind.hxx sc/inc/reffind.hxx
--- sc/inc/reffind.hxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/inc/reffind.hxx	2006-08-24 10:45:04.000000000 -0400
@@ -39,6 +39,9 @@
 #ifndef _STRING_HXX //autogen
 #include <tools/string.hxx>
 #endif
+#ifndef SC_ADDRESS_HXX
+#include "address.hxx"
+#endif
 
 class ScDocument;
 
@@ -48,6 +51,7 @@ class ScRefFinder
 {
 private:
 	String		aFormula;
+	ScAddress::Convention eConv;
 	ScDocument*	pDoc;
 	xub_StrLen	nFound;
 	xub_StrLen	nSelStart;
@@ -56,7 +60,9 @@ private:
 public:
 	static const sal_Unicode __FAR_DATA pDelimiters[];
 
-	ScRefFinder( const String& rFormula, ScDocument* pDocument = NULL );
+	ScRefFinder( const String& rFormula,
+		     ScDocument* pDocument = NULL,
+		     ScAddress::Convention eConvP = ScAddress::CONV_OOO );
 	~ScRefFinder();
 
 	const String&	GetText() const		{ return aFormula; }
diff -r -u -p sc/inc/scfuncs.hrc sc/inc/scfuncs.hrc
--- sc/inc/scfuncs.hrc	2006-09-05 23:35:37.000000000 -0400
+++ sc/inc/scfuncs.hrc	2006-08-24 10:47:20.000000000 -0400
@@ -300,6 +300,8 @@
 #define HID_FUNC_TABELLEN			(HID_SC_FUNC_DUMMY+(ID_FUNCTION_GRP_TABLE*ID_FUNCTION_OFFSET)+19)
 #define HID_FUNC_HYPERLINK			(HID_SC_FUNC_DUMMY+(ID_FUNCTION_GRP_TABLE*ID_FUNCTION_OFFSET)+20)
 #define HID_FUNC_GETPIVOTDATA		(HID_SC_FUNC_DUMMY+(ID_FUNCTION_GRP_TABLE*ID_FUNCTION_OFFSET)+21)
+#define HID_FUNC_INDIREKT_XL			(HID_SC_FUNC_DUMMY+(ID_FUNCTION_GRP_TABLE*ID_FUNCTION_OFFSET)+22)
+#define HID_FUNC_ADRESSE_XL			(HID_SC_FUNC_DUMMY+(ID_FUNCTION_GRP_TABLE*ID_FUNCTION_OFFSET)+23)
 
 #define HID_FUNC_CODE				(HID_SC_FUNC_DUMMY+(ID_FUNCTION_GRP_TEXT*ID_FUNCTION_OFFSET)+1)
 #define HID_FUNC_DM					(HID_SC_FUNC_DUMMY+(ID_FUNCTION_GRP_TEXT*ID_FUNCTION_OFFSET)+2)
diff -r -u -p sc/inc/sc.hrc sc/inc/sc.hrc
--- sc/inc/sc.hrc	2006-09-05 23:35:37.000000000 -0400
+++ sc/inc/sc.hrc	2006-08-24 10:45:04.000000000 -0400
@@ -805,6 +805,7 @@
 #define FID_TAB_APPEND			(TAB_POPUP_START+5)
 #define FID_TAB_INDEX			(TAB_POPUP_START+6)
 #define FID_TAB_RTL				(TAB_POPUP_START+7)
+#define FID_TAB_USE_R1C1		(TAB_POPUP_START+8)
 
 #define TAB_POPUP_END			(DATA_MENU_END + 20)
 
diff -r -u -p sc/sdi/docsh.sdi sc/sdi/docsh.sdi
--- sc/sdi/docsh.sdi	2006-09-05 23:35:37.000000000 -0400
+++ sc/sdi/docsh.sdi	2006-08-24 10:45:04.000000000 -0400
@@ -68,6 +68,7 @@ interface TableSelection
 	FID_DELETE_TABLE	[ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ]
 	FID_TAB_RENAME		[ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ]
 	FID_TAB_RTL			[ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ]
+	FID_TAB_USE_R1C1	[ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ]
 
 	SID_TABLE_ACTIVATE	[ ExecMethod = Execute; ]
 }
diff -r -u -p sc/sdi/scalc.sdi sc/sdi/scalc.sdi
--- sc/sdi/scalc.sdi	2006-09-05 23:35:37.000000000 -0400
+++ sc/sdi/scalc.sdi	2006-08-24 10:45:04.000000000 -0400
@@ -7754,3 +7754,30 @@ SfxBoolItem SheetRightToLeft FID_TAB_RTL
 ]
 
 
+//--------------------------------------------------------------------------
+SfxBoolItem SheetUseR1C1	FID_TAB_USE_R1C1
+
+[
+	/* flags */
+	AutoUpdate	= FALSE,
+	Cachable = Cachable,
+	FastCall = FALSE,
+	HasCoreId = FALSE,
+	HasDialog = FALSE,
+	ReadOnlyDoc = TRUE,
+	Toggle = FALSE,
+	Container = FALSE,
+	RecordAbsolute = FALSE,
+	RecordPerSet;
+	Synchron;
+
+	Readonly = FALSE,
+
+	/* config */
+	AccelConfig = TRUE,
+	MenuConfig = TRUE,
+	StatusBarConfig = FALSE,
+	ToolBoxConfig = TRUE,
+	GroupId = GID_FORMAT;
+]
+
diff -r -u -p sc/source/core/data/attrib.cxx sc/source/core/data/attrib.cxx
--- sc/source/core/data/attrib.cxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/source/core/data/attrib.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -522,6 +522,7 @@ SfxItemPresentation ScRangeItem::GetPres
 		case SFX_ITEM_PRESENTATION_NAMELESS:
 		{
 			String aText;
+			/* Always use OOo:A1 format */
 			aRange.Format( aText );
 			rText += aText;
 		}
diff -r -u -p sc/source/core/data/cell2.cxx sc/source/core/data/cell2.cxx
--- sc/source/core/data/cell2.cxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/source/core/data/cell2.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -242,7 +242,8 @@ void ScEditCell::SetTextObject( const Ed
 
 //---------------------------------------------------------------------
 
-void ScFormulaCell::GetEnglishFormula( String& rFormula, BOOL bCompileXML ) const
+void ScFormulaCell::GetEnglishFormula( String& rFormula, BOOL bCompileXML,
+									   ScAddress::Convention conv ) const
 {
     //! mit GetFormula zusammenfassen !!!
 
@@ -267,7 +268,7 @@ void ScFormulaCell::GetEnglishFormula( S
                 pCell = NULL;
             if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
             {
-                ((ScFormulaCell*)pCell)->GetEnglishFormula(rFormula, bCompileXML);
+                ((ScFormulaCell*)pCell)->GetEnglishFormula(rFormula, bCompileXML, conv);
                 return;
             }
             else
@@ -299,7 +300,8 @@ void ScFormulaCell::GetEnglishFormula( S
     }
 }
 
-void ScFormulaCell::GetEnglishFormula( rtl::OUStringBuffer& rBuffer, BOOL bCompileXML ) const
+void ScFormulaCell::GetEnglishFormula( rtl::OUStringBuffer& rBuffer, BOOL bCompileXML,
+									   ScAddress::Convention conv ) const
 {
     //! mit GetFormula zusammenfassen !!!
 
@@ -324,7 +326,7 @@ void ScFormulaCell::GetEnglishFormula( r
                 pCell = NULL;
             if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
             {
-                ((ScFormulaCell*)pCell)->GetEnglishFormula(rBuffer, bCompileXML);
+				((ScFormulaCell*)pCell)->GetEnglishFormula(rBuffer, bCompileXML, conv);
                 return;
             }
             else
@@ -1385,7 +1387,7 @@ void ScFormulaCell::CompileDBFormula( BO
         if ( bRecompile )
         {
             String aFormula;
-            GetFormula( aFormula );
+            GetFormula( aFormula, ScAddress::CONV_OOO);
             if ( GetMatrixFlag() != MM_NONE && aFormula.Len() )
             {
                 if ( aFormula.GetChar( aFormula.Len()-1 ) == '}' )
@@ -1397,6 +1399,7 @@ void ScFormulaCell::CompileDBFormula( BO
             pDocument->RemoveFromFormulaTree( this );
             pCode->Clear();
             aErgString = aFormula;
+			nErgConv = ScAddress::CONV_OOO;
         }
     }
     else if ( !pCode->GetLen() && aErgString.Len() )
@@ -1432,7 +1435,7 @@ void ScFormulaCell::CompileNameFormula( 
         if ( bRecompile )
         {
             String aFormula;
-            GetFormula( aFormula );
+            GetFormula( aFormula, ScAddress::CONV_OOO);
             if ( GetMatrixFlag() != MM_NONE && aFormula.Len() )
             {
                 if ( aFormula.GetChar( aFormula.Len()-1 ) == '}' )
@@ -1444,6 +1447,7 @@ void ScFormulaCell::CompileNameFormula( 
             pDocument->RemoveFromFormulaTree( this );
             pCode->Clear();
             aErgString = aFormula;
+			nErgConv = ScAddress::CONV_OOO;
         }
     }
     else if ( !pCode->GetLen() && aErgString.Len() )
diff -r -u -p sc/source/core/data/cell.cxx sc/source/core/data/cell.cxx
--- sc/source/core/data/cell.cxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/source/core/data/cell.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -542,7 +542,9 @@ ScFormulaCell::ScFormulaCell() :
 }
 
 ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
-							  const String& rFormula, BYTE cMatInd ) :
+							  const String& rFormula,
+							  ScAddress::Convention eConv,
+							  BYTE cMatInd ) :
 	ScBaseCell( CELLTYPE_FORMULA ),
 	nErgValue( 0.0 ),
 	pCode( NULL ),
@@ -570,7 +572,7 @@ ScFormulaCell::ScFormulaCell( ScDocument
 	cMatrixFlag ( cMatInd ),
 	aPos( rPos )
 {
-	Compile( rFormula, TRUE );	// bNoListening, erledigt Insert
+	Compile( rFormula, TRUE, eConv );	// bNoListening, erledigt Insert
 }
 
 // Wird von den Importfiltern verwendet
@@ -625,6 +627,7 @@ ScFormulaCell::ScFormulaCell( ScDocument
 	SvtListener(),
 	aErgString( rScFormulaCell.aErgString ),
 	nErgValue( rScFormulaCell.nErgValue ),
+	nErgConv( rScFormulaCell.nErgConv ),
 	pDocument( pDoc ),
 	pPrevious(0),
 	pNext(0),
@@ -782,6 +785,7 @@ ScFormulaCell::ScFormulaCell( ScDocument
 		if( cFlags & 0x10 )
 		{
 			rStream.ReadByteString( aErgString, rStream.GetStreamCharSet() );
+			nErgConv = ScAddress::CONV_OOO;
 			bIsValue = FALSE;
 		}
 		pCode->Load( rStream, nVer, aPos );
@@ -917,7 +921,7 @@ ScBaseCell* ScFormulaCell::Clone( ScDocu
 	return pCell;
 }
 
-void ScFormulaCell::GetFormula( String& rFormula ) const
+void ScFormulaCell::GetFormula( String& rFormula, ScAddress::Convention eConv ) const
 {
 	if( pCode->GetError() && !pCode->GetLen() )
 	{
@@ -941,7 +945,7 @@ void ScFormulaCell::GetFormula( String& 
 			}
 			if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
 			{
-				((ScFormulaCell*)pCell)->GetFormula(rFormula);
+				((ScFormulaCell*)pCell)->GetFormula(rFormula, eConv);
 				return;
 			}
 			else
@@ -983,7 +987,8 @@ void ScFormulaCell::GetResultDimensions(
 	}
 }
 
-void ScFormulaCell::Compile( const String& rFormula, BOOL bNoListening )
+void ScFormulaCell::Compile( const String& rFormula, BOOL bNoListening,
+							 ScAddress::Convention eConv )
 {
 	if ( pDocument->IsClipOrUndo() ) return;
 	BOOL bWasInFormulaTree = pDocument->IsInFormulaTree( this );
@@ -996,7 +1001,7 @@ void ScFormulaCell::Compile( const Strin
 	ScCompiler aComp(pDocument, aPos);
 	if ( pDocument->IsImportingXML() )
 		aComp.SetCompileEnglish( TRUE );
-	pCode = aComp.CompileString( rFormula );
+	pCode = aComp.CompileString( rFormula, eConv );
 	if ( pCodeOld )
 		delete pCodeOld;
 	if( !pCode->GetError() )
@@ -1026,7 +1031,7 @@ void ScFormulaCell::CompileTokenArray( B
 {
 	// Noch nicht compiliert?
 	if( !pCode->GetLen() && aErgString.Len() )
-		Compile( aErgString );
+		Compile( aErgString, nErgConv );
 	else if( bCompile && !pDocument->IsClipOrUndo() && !pCode->GetError() )
 	{
 		// RPN-Laenge kann sich aendern
@@ -1121,7 +1126,7 @@ void ScFormulaCell::CalcAfterLoad()
 	// aber kein TokenArray
 	if( !pCode->GetLen() && aErgString.Len() )
 	{
-		Compile( aErgString, TRUE );
+		Compile( aErgString, TRUE, nErgConv );
 		aErgString.Erase();
 		bDirty = TRUE;
 		bNewCompiled = TRUE;
diff -r -u -p sc/source/core/data/column3.cxx sc/source/core/data/column3.cxx
--- sc/source/core/data/column3.cxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/source/core/data/column3.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -1261,7 +1261,8 @@ void ScColumn::StartListeningInArea( SCR
 
 
 //	TRUE = Zahlformat gesetzt
-BOOL ScColumn::SetString( SCROW nRow, SCTAB nTab, const String& rString )
+BOOL ScColumn::SetString( SCROW nRow, SCTAB nTab, const String& rString,
+						  ScAddress::Convention conv )
 {
 	BOOL bNumFmtSet = FALSE;
 	if (VALIDROW(nRow))
@@ -1298,7 +1299,7 @@ BOOL ScColumn::SetString( SCROW nRow, SC
 					pNewCell = new ScStringCell( rString );
 				else											// =Formel
 					pNewCell = new ScFormulaCell( pDocument,
-						ScAddress( nCol, nRow, nTab ), rString, 0 );
+						ScAddress( nCol, nRow, nTab ), rString, conv, 0 );
 			}
 			else if ( cFirstChar == '\'')						// 'Text
 				pNewCell = new ScStringCell( rString.Copy(1) );
diff -r -u -p sc/source/core/data/conditio.cxx sc/source/core/data/conditio.cxx
--- sc/source/core/data/conditio.cxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/source/core/data/conditio.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -536,6 +536,8 @@ void ScConditionEntry::CompileXML()
     if ( aSrcString.Len() )
     {
         ScAddress aNew;
+		/* XML is always in OOo:A1 format, although R1C1 would be more amenable
+		 * to compression */
         if ( aNew.Parse( aSrcString, pDoc ) & SCA_VALID )
             aSrcPos = aNew;
         // if the position is invalid, there isn't much we can do at this time
diff -r -u -p sc/source/core/data/documen2.cxx sc/source/core/data/documen2.cxx
--- sc/source/core/data/documen2.cxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/source/core/data/documen2.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -374,6 +374,7 @@ ScDocument::ScDocument( ScDocumentMode	e
         nInDdeLinkUpdate( 0 ),
         bInUnoBroadcast( FALSE ),
         bInUnoListenerCall( FALSE ),
+        eAddrConv( ScAddress::CONV_OOO ),
         bStyleSheetUsageInvalid( TRUE )
 {
 	eSrcSet = gsl_getSystemTextEncoding();
diff -r -u -p sc/source/core/data/documen3.cxx sc/source/core/data/documen3.cxx
--- sc/source/core/data/documen3.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/data/documen3.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -399,6 +399,16 @@ BOOL ScDocument::IsLinked( SCTAB nTab ) 
 	return FALSE;
 }
 
+ScAddress::Convention ScDocument::GetAddressConvention() const
+{
+	return eAddrConv;
+}
+
+void ScDocument::SetAddressConvention( ScAddress::Convention eConv )
+{
+	eAddrConv = eConv;
+}
+
 BOOL ScDocument::GetLinkMode( SCTAB nTab ) const
 {
 	if (ValidTab(nTab) && pTab[nTab])
diff -r -u -p sc/source/core/data/documen4.cxx sc/source/core/data/documen4.cxx
--- sc/source/core/data/documen4.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/data/documen4.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -152,7 +152,7 @@ void ScDocument::InsertMatrixFormula(SCC
 	if (pArr)
 		pCell = new ScFormulaCell( this, aPos, pArr, MM_FORMULA );
 	else
-		pCell = new ScFormulaCell( this, aPos, rFormula, MM_FORMULA );
+		pCell = new ScFormulaCell( this, aPos, rFormula, ScAddress::CONV_UNSPECIFIED, MM_FORMULA );
 	pCell->SetMatColsRows( nCol2 - nCol1 + 1, nRow2 - nRow1 + 1 );
 	for (i = 0; i <= MAXTAB; i++)
 	{
@@ -283,7 +283,7 @@ void ScDocument::InsertTableOp(const ScT
 	}
     aForString += ')';
 
-    ScFormulaCell aRefCell( this, ScAddress( nCol1, nRow1, nTab1 ), aForString, 0l );
+    ScFormulaCell aRefCell( this, ScAddress( nCol1, nRow1, nTab1 ), aForString, ScAddress::CONV_OOO, 0l );
     for( j = nCol1; j <= nCol2; j++ )
         for( k = nRow1; k <= nRow2; k++ )
             for (i = 0; i <= MAXTAB; i++)
diff -r -u -p sc/source/core/data/table6.cxx sc/source/core/data/table6.cxx
--- sc/source/core/data/table6.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/data/table6.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -118,7 +118,7 @@ BOOL ScTable::SearchCell(const SvxSearch
 			case SVX_SEARCHIN_FORMULA:
 			{
 				if ( eCellType == CELLTYPE_FORMULA )
-					((ScFormulaCell*)pCell)->GetFormula( aString );
+					((ScFormulaCell*)pCell)->GetFormula( aString, ScAddress::CONV_OOO );
 				else if ( eCellType == CELLTYPE_EDIT )
 					bMultiLine = lcl_GetTextWithBreaks(
 						*(const ScEditCell*)pCell, pDocument, aString );
@@ -281,7 +281,7 @@ BOOL ScTable::SearchCell(const SvxSearch
 				}
 				ScAddress aAdr( nCol, nRow, nTab );
 				ScFormulaCell* pFCell = new ScFormulaCell( pDocument, aAdr,
-					aString, cMatrixFlag );
+					aString, ScAddress::CONV_OOO, cMatrixFlag );
                 SCCOL nMatCols;
                 SCROW nMatRows;
 				((ScFormulaCell*)pCell)->GetMatColsRows( nMatCols, nMatRows );
diff -r -u -p sc/source/core/inc/interpre.hxx sc/source/core/inc/interpre.hxx
--- sc/source/core/inc/interpre.hxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/inc/interpre.hxx	2006-08-24 10:45:05.000000000 -0400
@@ -424,7 +424,9 @@ void ScDBStdDevP();
 void ScDBVar();
 void ScDBVarP();
 void ScIndirect();
+void ScIndirectXL();
 void ScAdress();
+void ScAdressXL();
 void ScOffset();
 void ScIndex();
 void ScMultiArea();
diff -r -u -p sc/source/core/src/compiler.src sc/source/core/src/compiler.src
--- sc/source/core/src/compiler.src	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/src/compiler.src	2006-08-24 10:45:05.000000000 -0400
@@ -1092,12 +1092,24 @@ Resource RID_SC_FUNCTION_NAMES
 		Text [ en-US ] = "INDIRECT" ;
 		Text [ x-comment ] = " ";
 	};
+	String SC_OPCODE_INDIRECT_XL
+	{
+		Text [ de ] = "INDIREKT_XL" ;
+		Text [ en-US ] = "INDIRECT_XL" ;
+		Text [ x-comment ] = " ";
+	};
 	String SC_OPCODE_ADRESS
 	{
 		Text [ de ] = "ADRESSE" ;
 		Text [ en-US ] = "ADDRESS" ;
 		Text [ x-comment ] = " ";
 	};
+	String SC_OPCODE_ADRESS_XL
+	{
+		Text [ de ] = "ADRESSE_XL" ;
+		Text [ en-US ] = "ADDRESS_XL" ;
+		Text [ x-comment ] = " ";
+	};
 	String SC_OPCODE_MATCH
 	{
 		Text [ de ] = "VERGLEICH" ;
@@ -1879,7 +1891,9 @@ Resource RID_SC_FUNCTION_NAMES_ENGLISH
 	String SC_OPCODE_DB_VAR { Text = "DVAR" ; };
 	String SC_OPCODE_DB_VAR_P { Text = "DVARP" ; };
 	String SC_OPCODE_INDIRECT { Text = "INDIRECT" ; };
+	String SC_OPCODE_INDIRECT_XL { Text = "INDIRECT_XL" ; };
 	String SC_OPCODE_ADRESS { Text = "ADDRESS" ; };
+	String SC_OPCODE_ADRESS_XL { Text = "ADDRESS_XL" ; };
 	String SC_OPCODE_MATCH { Text = "MATCH" ; };
 	String SC_OPCODE_COUNT_EMPTY_CELLS { Text = "COUNTBLANK" ; };
 	String SC_OPCODE_COUNT_IF { Text = "COUNTIF" ; };
diff -r -u -p sc/source/core/tool/address.cxx sc/source/core/tool/address.cxx
--- sc/source/core/tool/address.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/tool/address.cxx	2006-09-05 23:04:18.000000000 -0400
@@ -36,20 +36,609 @@
 // MARKER(update_precomp.py): autogen include statement, do not remove
 #include "precompiled_sc.hxx"
 
-
 #include "address.hxx"
 #include "global.hxx"
 #include "compiler.hxx"
 #include "document.hxx"
 
 #include "globstr.hrc"
+#include <sal/alloca.h>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <sfx2/objsh.hxx>
+#include <tools/urlobj.hxx>
+using namespace ::com::sun::star;
+
+////////////////////////////////////////////////////////////////////////////
+const ScAddress::Details ScAddress::detailsOOOa1( CONV_OOO, 0, 0 );
+
+ScAddress::Details::Details ( const ScDocument* pDoc,
+							  const ScAddress & rAddr ) :
+	eConv( pDoc->GetAddressConvention() ),
+	nRow( rAddr.Row() ),
+	nCol( rAddr.Col() )
+{
+}
+
+void ScAddress::Details::SetPos ( const ScDocument* pDoc,
+								  const ScAddress & rAddr )
+{
+	nRow  = rAddr.Row();
+	nCol  = rAddr.Col();
+	eConv = pDoc->GetAddressConvention();
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+#include <iostream>
+
+static long int
+sal_Unicode_strtol ( const sal_Unicode*  p,
+					 const sal_Unicode** pEnd )
+{
+	long int accum = 0, prev = 0;
+	bool is_neg = false;
+
+	if( *p == '-' )
+	{
+		is_neg = true;
+		p++;
+	}
+	else if( *p == '+' )
+		p++;
+
+	while (CharClass::isAsciiDigit( *p ))
+	{
+		accum = accum * 10 + *p - '0';
+		if( accum < prev )
+		{
+			*pEnd = NULL;
+			return 0;
+		}
+		prev = accum;
+		p++;
+	}
+
+	*pEnd = p;
+	return is_neg ? -accum : accum;
+}
+
+// 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 *
+lcl_XL_ParseSheetRef( const sal_Unicode *start,
+					  ScAddress *pAddr,
+					  const ScDocument* pDoc,
+					  const String& rDocName,
+					  String& rExternTabName,
+					  bool allow_3d )
+{
+	String aTabName;
+	SCTAB  nTab;
+	const sal_Unicode *p = start;
+
+	pAddr->SetTab( 0 );
+	if( *p == '\'' ) // XL only seems to use single quotes for sheet names
+	{
+		for( p++; *p ; )
+		{
+			if( *p == '\'' )
+			{
+				if( p[1] != '\'' )	// end quote
+					break;
+				p++;	// 2 quotes in a row are a quote in a the name
+			}
+			aTabName += *p++;
+		}
+		if( *p++ != '\'' )
+			return NULL;
+	}
+	else
+	{
+		bool only_digits = TRUE;
+
+		/*
+		 * Valid: Normal!a1
+		 * Valid: x.y!a1
+		 * Invalid: .y!a1
+		 *
+		 * Some names starting with digits are actually valid, but
+		 * unparse quoted. Things are quite tricky: most sheet names
+		 * starting with a digit are ok, but not those starting with
+		 * "[0-9]*\." or "[0-9]+[eE]".
+		 * 
+		 * Valid: 42!a1
+		 * Valid: 4x!a1
+		 * Invalid: 1.!a1
+		 * Invalid: 1e!a1
+		 */
+		while( 1 )
+		{
+			const sal_Unicode uc = *p;
+			if( CharClass::isAsciiAlpha( uc ) || uc == '_' )
+			{
+				if( only_digits && p != start &&
+				   (uc == 'e' || uc == 'E' ) )
+				{
+					p = start;
+					break;
+				}
+				only_digits = FALSE;
+				p++;
+			}
+			else if( CharClass::isAsciiDigit( uc ))
+			{
+				p++;
+			}
+			else if( uc == '.' )
+			{
+				if( only_digits ) // Valid, except after only digits.
+				{
+					p = start;
+					break;
+				}
+				p++;
+			} else 
+				break;
+		}
+
+		if( *p != '!' &&( !allow_3d || *p != ':' ) )
+			return start;
+
+		aTabName.Append( start, p - start );
+	}
+
+	if( pDoc )
+	{
+		if( rDocName.Len() > 0 )
+		{
+			// This is a simplification of the OOo code which does an
+			// optimization to manually construct the DocTab before calling
+			// GetDocTabName
+			String aDocTab = ScGlobal::GetDocTabName( rDocName, aTabName );
+			if( !pDoc->GetTable( aDocTab, nTab ) &&
+				 pDoc->ValidTabName( aTabName ) &&
+				!pDoc->GetTable( aDocTab, nTab ) )
+			{
+				rExternTabName = aDocTab;
+			}
+		}
+		else if( !pDoc->GetTable( aTabName, nTab ) )
+			return start;
+	}
+
+	pAddr->SetTab( nTab );
+	return p;
+}
+
+static const sal_Unicode*
+lcl_ScRange_Parse_XL_Header( ScRange& r,
+							 const sal_Unicode* p,
+							 const ScDocument* pDoc,
+							 String& rExternDocName,
+							 String& rStartTabName,
+							 String& rEndTabName,
+							 USHORT& nFlags )
+{
+	const sal_Unicode* startTabs, *start = p;
+
+	// Is this an external reference ?
+	rStartTabName.Erase();
+	rEndTabName.Erase();
+	if( *p == '[' )
+	{
+		p++;
+		// TODO : Get more detail on how paths are quoted
+		// 1) I suspect only single quote is correct
+		// 2) check whether this is another doubled quote rather than a
+		// 	  backslash
+		if( *p == '\'' || *p == '\"' )
+		{
+			for( const sal_Unicode cQuote = *p++; *p && *p != cQuote ; )
+			{
+				if( *p == '\\' && p[1] )
+					p++;
+				rExternDocName += *p++;
+			}
+		}
+		else
+		{
+			p = ScGlobal::UnicodeStrChr( start+1, ']' );
+			if( p == NULL )
+				return start;
+			rExternDocName.Append( start+1, p-(start+1) );
+		}
+
+		rExternDocName = ScGlobal::GetAbsDocName( rExternDocName,
+			pDoc->GetDocumentShell() );
+		if( *p != ']' )
+			return start;
+		p++;
+	}
+
+	startTabs = p;
+	p = lcl_XL_ParseSheetRef( p, &r.aStart, pDoc, rExternDocName, rStartTabName, TRUE );
+	if( NULL == p )
+		return start;		// invalid tab
+	if( p != startTabs )
+	{
+		nFlags |= SCA_VALID_TAB | SCA_TAB_3D | SCA_TAB_ABSOLUTE;
+		if( *p == ':' )	// 3d ref
+		{
+			p = lcl_XL_ParseSheetRef( p+1, &r.aEnd, pDoc, rExternDocName, rEndTabName, FALSE );
+			if( p == NULL )
+				return start; // invalid tab
+			nFlags |= SCA_VALID_TAB2 | SCA_TAB2_3D | SCA_TAB2_ABSOLUTE;
+		}
+		else
+			r.aEnd.SetTab( 0 );
+
+		if( *p++ != '!' )
+			return start;	// syntax error
+	}
+	else
+	{
+		nFlags |= SCA_VALID_TAB | SCA_VALID_TAB2;
+		r.aEnd.SetTab( 0 );
+	}
+
+	return p;
+}
+
+static USHORT
+lcl_XL_LinkSheetRef( ScRange& r,
+					 ScDocument* pDoc,
+					 const String& rExternDocName,
+					 const String& rStartTabName,
+					 const String& rEndTabName,
+					 USHORT nFlags )
+{
+	SCTAB nTab;
+
+	if( rExternDocName.Len() > 0 )
+	{
+		String aDocName = ScGlobal::GetAbsDocName( rExternDocName,
+												   pDoc->GetDocumentShell() );
+
+		String aDocTab;
+	   
+		aDocTab = ScGlobal::GetDocTabName( aDocName, rStartTabName );
+		if( !pDoc->LinkExternalTab( nTab, aDocTab, rExternDocName, rStartTabName ) )
+			return 0;
+		r.aStart.SetTab( nTab );
+
+		if( rEndTabName.Len() > 0 &&
+			rStartTabName != rEndTabName )
+		{
+			aDocTab = ScGlobal::GetDocTabName( aDocName, rEndTabName );
+			if( !pDoc->LinkExternalTab( nTab, aDocTab, rExternDocName, rEndTabName ) )
+			{
+				DBG_ASSERT( rRange.IsValid(), "lcl_XL_LinkSheetRef - unable to link endTab of 3d ref" );
+				return 0;
+			}
+		}
+		r.aEnd.SetTab( nTab );
+	}
+
+	return nFlags;
+}
+
+
+static const sal_Unicode*
+lcl_r1c1_get_col( const sal_Unicode* p,
+				  const ScAddress::Details& rDetails,
+				  ScAddress* pAddr, USHORT* nFlags )
+{
+	const sal_Unicode *pEnd;
+	long int n;
+	bool isRelative;
+
+	if( p[0] == '\0' )
+		return NULL;
+
+	p++;
+	if( (isRelative = (*p == '[') ) )
+		p++;
+	n = sal_Unicode_strtol( p, &pEnd );
+	if( NULL == pEnd )
+		return NULL;
+
+	if( p == pEnd )	// C is a relative ref with offset 0
+	{
+		if( isRelative )
+			return NULL;
+		n = rDetails.nCol;
+	}
+	else if( isRelative )
+	{
+		if( *pEnd != ']' )
+			return NULL;
+		n += rDetails.nCol;
+		pEnd++;
+	}
+	else
+	{
+		*nFlags |= SCA_COL_ABSOLUTE;
+		n--;
+	}
+
+	if( n < 0 || n >= MAXCOLCOUNT )
+		return NULL;
+	pAddr->SetCol( static_cast<SCROW>( n ) );
+	*nFlags |= SCA_VALID_COL;
+
+	return pEnd;
+}
+static inline const sal_Unicode*
+lcl_r1c1_get_row( const sal_Unicode* p,
+				  const ScAddress::Details& rDetails,
+				  ScAddress* pAddr, USHORT* nFlags )
+{
+	const sal_Unicode *pEnd;
+	long int n;
+	bool isRelative;
+
+	if( p[0] == '\0' )
+		return NULL;
+
+	p++;
+	if( (isRelative = (*p == '[') ) )
+		p++;
+	n = sal_Unicode_strtol( p, &pEnd );
+	if( NULL == pEnd )
+		return NULL;
+
+	if( p == pEnd )	// R is a relative ref with offset 0
+	{
+		if( isRelative )
+			return NULL;
+		n = rDetails.nRow;
+	}
+	else if( isRelative )
+	{
+		if( *pEnd != ']' )
+			return NULL;
+		n += rDetails.nRow;
+		pEnd++;
+	}
+	else
+	{
+		*nFlags |= SCA_ROW_ABSOLUTE;
+		n--;
+	}
+
+	if( n < 0 || n >= MAXROWCOUNT )
+		return NULL;
+	pAddr->SetRow( static_cast<SCROW>( n ) );
+	*nFlags |= SCA_VALID_ROW;
+
+	return pEnd;
+}
+
+static USHORT
+lcl_ScRange_Parse_XL_R1C1( ScRange& r,
+						   const sal_Unicode* p,
+						   ScDocument* pDoc,
+						   const ScAddress::Details& rDetails,
+						   BOOL bOnlyAcceptSingle )
+{
+	const sal_Unicode* pTmp;
+	String aExternDocName, aStartTabName, aEndTabName;
+	USHORT nFlags = SCA_VALID | SCA_VALID_TAB, nFlags2 = SCA_VALID_TAB2;
+
+#if 0
+	{
+		ByteString	aStr(p, RTL_TEXTENCODING_UTF8);
+		aStr.Append(static_cast< char >(0));
+		std::cerr << "parse::XL::R1C1 \'" << aStr.GetBuffer() << '\'' << std::endl;
+	}
+#endif
+	p = lcl_ScRange_Parse_XL_Header( r, p, pDoc,
+		aExternDocName, aStartTabName, aEndTabName, nFlags );
+	if( NULL == p )
+		return 0;
+
+	if( *p == 'R' || *p == 'r' )
+	{
+		if( NULL == (p = lcl_r1c1_get_row( p, rDetails, &r.aStart, &nFlags )) )
+			goto failed;
+
+		if( *p != 'C' && *p != 'c' )	// full row R#
+		{
+			if( p[0] != ':' || (p[1] != 'R' && p[1] != 'r' ) ||
+				NULL == (pTmp = lcl_r1c1_get_row( p+1, rDetails, &r.aEnd, &nFlags2 )))
+			{	// Fallback to just the initial R
+				nFlags |= (nFlags << 4);
+				r.aEnd.SetRow( r.aStart.Row() );
+			} else
+				nFlags |= (nFlags2 << 4);
+
+			nFlags |= 
+				SCA_VALID_COL | SCA_VALID_COL2 |
+				SCA_COL_ABSOLUTE | SCA_COL2_ABSOLUTE;
+			r.aStart.SetCol( 0 );
+			r.aEnd.SetCol( MAXCOL );
+
+			return bOnlyAcceptSingle ? 0 : lcl_XL_LinkSheetRef( r, pDoc,
+				aExternDocName, aStartTabName, aEndTabName, nFlags );
+		}
+		else if( NULL == (p = lcl_r1c1_get_col( p, rDetails, &r.aStart, &nFlags )))
+			goto failed;
+
+		if( p[0] != ':' ||
+			(p[1] != 'R' && p[1] != 'r') ||
+		    NULL == (pTmp = lcl_r1c1_get_row( p+1, rDetails, &r.aEnd, &nFlags2 )) ||
+		    (*pTmp != 'C' && *pTmp != 'c') ||
+		    NULL == (pTmp = lcl_r1c1_get_col( pTmp, rDetails, &r.aEnd, &nFlags2 )))
+		{
+			return bOnlyAcceptSingle ? lcl_XL_LinkSheetRef( r, pDoc,
+				aExternDocName, aStartTabName, aEndTabName, nFlags ) : 0;
+		}
+
+		nFlags |= (nFlags2 << 4);
+		return bOnlyAcceptSingle ? 0 : lcl_XL_LinkSheetRef( r, pDoc,
+			aExternDocName, aStartTabName, aEndTabName, nFlags );
+	}
+	else if( *p == 'C' || *p == 'c' )	// full col C#
+	{
+		if( NULL == (p = lcl_r1c1_get_col( p, rDetails, &r.aStart, &nFlags )))
+			goto failed;
+
+		if( p[0] != ':' || (p[1] != 'C' && p[1] != 'c') ||
+			NULL == (pTmp = lcl_r1c1_get_col( p+1, rDetails, &r.aEnd, &nFlags2 )))
+		{	 // Fallback to just the initial C
+			nFlags |= (nFlags << 4);
+			r.aEnd.SetCol( r.aStart.Col() );
+		}
+		else
+			nFlags |= (nFlags2 << 4);
+
+		nFlags |= 
+			SCA_VALID_ROW | SCA_VALID_ROW2 |
+			SCA_ROW_ABSOLUTE | SCA_ROW2_ABSOLUTE;
+		r.aStart.SetRow( 0 );
+		r.aEnd.SetRow( MAXROW );
+
+		return bOnlyAcceptSingle ? 0 : lcl_XL_LinkSheetRef( r, pDoc,
+			aExternDocName, aStartTabName, aEndTabName, nFlags );
+	}
+
+failed :
+	return 0;
+}
+
+static inline const sal_Unicode*
+lcl_a1_get_col( const sal_Unicode* p, ScAddress* pAddr, USHORT* nFlags )
+{
+    SCCOL nCol;
+
+	if( *p == '$' )
+		*nFlags |= SCA_COL_ABSOLUTE, p++;
+
+	if( !CharClass::isAsciiAlpha( *p ) )
+		return NULL;
+
+	nCol = toupper( char(*p++) ) - 'A';
+	while (nCol <= MAXCOL && CharClass::isAsciiAlpha(*p))
+		nCol = ((nCol + 1) * 26) + toupper( char(*p++) ) - 'A';
+	if( nCol > MAXCOL || CharClass::isAsciiAlpha( *p ) )
+		return NULL;
 
+	*nFlags |= SCA_VALID_COL;
+	pAddr->SetCol( nCol );
 
-USHORT lcl_ConvertSingleRef( BOOL& bExternal, const sal_Unicode* p,
-            ScDocument* pDoc, ScAddress& rAddr )
+	return p;
+}
+
+static inline const sal_Unicode*
+lcl_a1_get_row( const sal_Unicode* p, ScAddress* pAddr, USHORT* nFlags )
 {
-    if ( !*p )
+	const sal_Unicode *pEnd;
+	long int n;
+
+	if( *p == '$' )
+		*nFlags |= SCA_ROW_ABSOLUTE, p++;
+
+	n = sal_Unicode_strtol( p, &pEnd ) - 1;
+	if( NULL == pEnd || p == pEnd || n < 0 || n > MAXROW )
+		return NULL;
+
+	*nFlags |= SCA_VALID_ROW;
+	pAddr->SetRow( static_cast<SCROW>(n) );
+
+	return pEnd;
+}
+
+static USHORT
+lcl_ScRange_Parse_XL_A1( ScRange& r,
+						 const sal_Unicode* p,
+						 ScDocument* pDoc,
+						 BOOL bOnlyAcceptSingle )
+{
+	const sal_Unicode* tmp1, *tmp2;
+	String aExternDocName, aStartTabName, aEndTabName;
+	USHORT nFlags = SCA_VALID | SCA_VALID_TAB, nFlags2 = SCA_VALID_TAB2;
+
+#if 0
+	{
+		ByteString	aStr(p, RTL_TEXTENCODING_UTF8);
+		aStr.Append(static_cast< char >(0));
+		std::cerr << "parse::XL::A1 \'" << aStr.GetBuffer() << '\'' << std::endl;
+	}
+#endif
+	p = lcl_ScRange_Parse_XL_Header( r, p, pDoc,
+		aExternDocName, aStartTabName, aEndTabName, nFlags );
+	if( NULL == p )
+		return 0;
+
+	tmp1 = lcl_a1_get_col( p, &r.aStart, &nFlags );
+	if( tmp1 == NULL )			// Is it a row only reference 3:5
+	{
+		if( bOnlyAcceptSingle )	// by definition full row refs are ranges
+			return 0;
+
+		tmp1 = lcl_a1_get_row( p, &r.aStart, &nFlags );
+		if( !tmp1 || *tmp1++ != ':' ) // Even a singleton requires ':' (eg 2:2)
+			return 0;
+		tmp2 = lcl_a1_get_row( tmp1, &r.aEnd, &nFlags2 );
+		if( !tmp2 )
+			return 0;
+
+		r.aStart.SetCol( 0 ); r.aEnd.SetCol( MAXCOL );
+		nFlags |= 
+			SCA_VALID_COL | SCA_VALID_COL2 |
+			SCA_COL_ABSOLUTE | SCA_COL2_ABSOLUTE;
+		nFlags |= (nFlags2 << 4);
+		return lcl_XL_LinkSheetRef( r, pDoc,
+			aExternDocName, aStartTabName, aEndTabName, nFlags );
+	}
+
+	tmp2 = lcl_a1_get_row( tmp1, &r.aStart, &nFlags );
+	if( tmp2 == NULL )			// check for col only reference F:H
+	{
+		if( bOnlyAcceptSingle )	// by definition full col refs are ranges
+			return 0;
+
+		if( *tmp1++ != ':' )	// Even a singleton requires ':' (eg F:F)
+			return 0;
+		tmp2 = lcl_a1_get_col( tmp1, &r.aEnd, &nFlags2 );
+		if( !tmp2 )
         return 0;
+
+		r.aStart.SetRow( 0 ); r.aEnd.SetRow( MAXROW );
+		nFlags |= 
+			SCA_VALID_ROW | SCA_VALID_ROW2 |
+			SCA_ROW_ABSOLUTE | SCA_ROW2_ABSOLUTE;
+		nFlags |= (nFlags2 << 4);
+		return lcl_XL_LinkSheetRef( r, pDoc,
+			aExternDocName, aStartTabName, aEndTabName, nFlags );
+	}
+
+	// prepare as if it's a singleton, in case we want to fall back */
+	r.aEnd = r.aStart;
+	if( *tmp2 != ':' )
+		return nFlags;
+
+	p = tmp2;
+	tmp1 = lcl_a1_get_col( p+1, &r.aEnd, &nFlags2 );
+	if( !tmp1 ) // strange, but valid singleton
+		return lcl_XL_LinkSheetRef( r, pDoc,
+			aExternDocName, aStartTabName, aEndTabName, nFlags );
+	tmp2 = lcl_a1_get_row( tmp1, &r.aEnd, &nFlags2 );
+	if( !tmp2 ) // strange, but valid singleton
+		return lcl_XL_LinkSheetRef( r, pDoc,
+			aExternDocName, aStartTabName, aEndTabName, nFlags );
+
+	nFlags |= (nFlags2 << 4);
+	return lcl_XL_LinkSheetRef( r, pDoc,
+		aExternDocName, aStartTabName, aEndTabName, nFlags );
+}
+
+static USHORT
+lcl_ScAddress_Parse_OOo( BOOL& bExternal, const sal_Unicode* p,
+						 ScDocument* pDoc, ScAddress& rAddr )
+{
     USHORT  nRes = 0;
     String  aDocName;       // der pure Dokumentenname
     String  aDocTab;        // zusammengesetzt fuer Table
@@ -113,7 +702,7 @@ USHORT lcl_ConvertSingleRef( BOOL& bExte
                     {
                         aDocName = ScGlobal::GetAbsDocName( aDocName,
                             pDoc->GetDocumentShell() );
-                        aDocTab = ScGlobal::GetDocTabName( aDocName, aTab );
+						aDocTab = ScGlobal::GetDocTabName( aDocName, aTab );
                         if ( !pDoc->GetTable( aDocTab, nTab ) )
                         {
                             // erst einfuegen, wenn Rest der Ref ok
@@ -217,13 +806,47 @@ USHORT lcl_ConvertSingleRef( BOOL& bExte
     return nRes;
 }
 
+static USHORT
+lcl_ScAddress_Parse ( BOOL& bExternal, const sal_Unicode* p,
+					  ScDocument* pDoc, ScAddress& rAddr,
+					  const ScAddress::Details& rDetails )
+{
+    if( !*p )
+        return 0;
+
+	switch (rDetails.eConv)
+	{
+	default :
+	case ScAddress::CONV_OOO:
+		{
+			return lcl_ScAddress_Parse_OOo( bExternal, p, pDoc, rAddr );
+		}
+
+	case ScAddress::CONV_XL_A1:
+		{
+			ScRange r;
+			USHORT nFlags = lcl_ScRange_Parse_XL_A1( r, p, pDoc, TRUE );
+			rAddr = r.aStart;
+			return nFlags;
+		}
+	case ScAddress::CONV_XL_R1C1:
+		{
+			ScRange r;
+			USHORT nFlags = lcl_ScRange_Parse_XL_R1C1( r, p, pDoc, rDetails, TRUE );
+			rAddr = r.aStart;
+			return nFlags;
+		}
+	}
+}
+
 
 bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
-            SCTAB nDefTab, ScRefAddress& rRefAddress )
+					   SCTAB nDefTab, ScRefAddress& rRefAddress,
+					   const ScAddress::Details& rDetails )
 {
     BOOL bExternal = FALSE;
     ScAddress aAddr( 0, 0, nDefTab );
-    USHORT nRes = lcl_ConvertSingleRef( bExternal, rRefString.GetBuffer(), pDoc, aAddr );
+    USHORT nRes = lcl_ScAddress_Parse( bExternal, rRefString.GetBuffer(), pDoc, aAddr, rDetails );
     if( nRes & SCA_VALID )
     {
         rRefAddress.Set( aAddr,
@@ -238,29 +861,32 @@ bool ConvertSingleRef( ScDocument* pDoc,
 
 
 bool ConvertDoubleRef( ScDocument* pDoc, const String& rRefString, SCTAB nDefTab,
-            ScRefAddress& rStartRefAddress, ScRefAddress& rEndRefAddress )
+					   ScRefAddress& rStartRefAddress, ScRefAddress& rEndRefAddress,
+					   const ScAddress::Details& rDetails )
 {
     BOOL bRet = FALSE;
+	// FIXME : This will break for Lotus
     xub_StrLen nPos = rRefString.Search(':');
     if (nPos != STRING_NOTFOUND)
     {
         String aTmp( rRefString );
         sal_Unicode* p = aTmp.GetBufferAccess();
         p[ nPos ] = 0;
-        if ( ConvertSingleRef( pDoc, p, nDefTab, rStartRefAddress ) )
+        if( ConvertSingleRef( pDoc, p, nDefTab, rStartRefAddress, rDetails ) )
         {
             nDefTab = rStartRefAddress.Tab();
-            bRet = ConvertSingleRef( pDoc, p + nPos + 1, nDefTab, rEndRefAddress );
+            bRet = ConvertSingleRef( pDoc, p + nPos + 1, nDefTab, rEndRefAddress, rDetails );
         }
     }
     return bRet;
 }
 
 
-USHORT ScAddress::Parse( const String& r, ScDocument* pDoc )
+USHORT ScAddress::Parse( const String& r, ScDocument* pDoc,
+						 const Details& rDetails)
 {
     BOOL bExternal = FALSE;
-    return lcl_ConvertSingleRef( bExternal, r.GetBuffer(), pDoc, *this );
+    return lcl_ScAddress_Parse( bExternal, r.GetBuffer(), pDoc, *this, rDetails );
 }
 
 
@@ -328,12 +954,13 @@ void ScRange::ExtendTo( const ScRange& r
         *this = rRange;
 }
 
-
-USHORT ScRange::Parse( const String& r, ScDocument* pDoc )
+static USHORT
+lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc )
 {
     USHORT nRes1 = 0, nRes2 = 0;
     xub_StrLen nTmp = 0;
     xub_StrLen nPos = STRING_NOTFOUND;
+
     while ( (nTmp = r.Search( ':', nTmp )) != STRING_NOTFOUND )
         nPos = nTmp++;      // der letzte zaehlt, koennte 'd:\...'!a1:a2 sein
     if (nPos != STRING_NOTFOUND)
@@ -342,21 +969,21 @@ USHORT ScRange::Parse( const String& r, 
         sal_Unicode* p = aTmp.GetBufferAccess();
         p[ nPos ] = 0;
         BOOL bExternal = FALSE;
-        if( nRes1 = lcl_ConvertSingleRef( bExternal, p, pDoc, aStart ) )
+        if( (nRes1 = lcl_ScAddress_Parse_OOo( bExternal, p, pDoc, aRange.aStart ) ) )
         {
-            aEnd = aStart;  // die Tab _muss_ gleich sein, so ist`s weniger Code
-            if ( nRes2 = lcl_ConvertSingleRef( bExternal, p + nPos+ 1, pDoc, aEnd ) )
+            aRange.aEnd = aRange.aStart;  // die Tab _muss_ gleich sein, so ist`s weniger Code
+            if ( (nRes2 = lcl_ScAddress_Parse_OOo( bExternal, p + nPos+ 1, pDoc, aRange.aEnd ) ) )
             {
-                if ( bExternal && aStart.Tab() != aEnd.Tab() )
+                if ( bExternal && aRange.aStart.Tab() != aRange.aEnd.Tab() )
                     nRes2 &= ~SCA_VALID_TAB;    // #REF!
                 else
                 {
                     // PutInOrder / Justify
                     USHORT nMask, nBits1, nBits2;
                     SCCOL nTempCol;
-                    if ( aEnd.Col() < (nTempCol = aStart.Col()) )
+                    if ( aRange.aEnd.Col() < (nTempCol = aRange.aStart.Col()) )
                     {
-                        aStart.SetCol(aEnd.Col()); aEnd.SetCol(nTempCol);
+                        aRange.aStart.SetCol(aRange.aEnd.Col()); aRange.aEnd.SetCol(nTempCol);
                         nMask = (SCA_VALID_COL | SCA_COL_ABSOLUTE);
                         nBits1 = nRes1 & nMask;
                         nBits2 = nRes2 & nMask;
@@ -364,9 +991,9 @@ USHORT ScRange::Parse( const String& r, 
                         nRes2 = (nRes2 & ~nMask) | nBits1;
                     }
                     SCROW nTempRow;
-                    if ( aEnd.Row() < (nTempRow = aStart.Row()) )
+                    if ( aRange.aEnd.Row() < (nTempRow = aRange.aStart.Row()) )
                     {
-                        aStart.SetRow(aEnd.Row()); aEnd.SetRow(nTempRow);
+                        aRange.aStart.SetRow(aRange.aEnd.Row()); aRange.aEnd.SetRow(nTempRow);
                         nMask = (SCA_VALID_ROW | SCA_ROW_ABSOLUTE);
                         nBits1 = nRes1 & nMask;
                         nBits2 = nRes2 & nMask;
@@ -374,9 +1001,9 @@ USHORT ScRange::Parse( const String& r, 
                         nRes2 = (nRes2 & ~nMask) | nBits1;
                     }
                     SCTAB nTempTab;
-                    if ( aEnd.Tab() < (nTempTab = aStart.Tab()) )
+                    if ( aRange.aEnd.Tab() < (nTempTab = aRange.aStart.Tab()) )
                     {
-                        aStart.SetTab(aEnd.Tab()); aEnd.SetTab(nTempTab);
+                        aRange.aStart.SetTab(aRange.aEnd.Tab()); aRange.aEnd.SetTab(nTempTab);
                         nMask = (SCA_VALID_TAB | SCA_TAB_ABSOLUTE | SCA_TAB_3D);
                         nBits1 = nRes1 & nMask;
                         nBits2 = nRes2 & nMask;
@@ -399,24 +1026,251 @@ USHORT ScRange::Parse( const String& r, 
     return nRes1;
 }
 
+USHORT ScRange::Parse( const String& r, ScDocument* pDoc,
+					   const ScAddress::Details& rDetails )
+{
+    if ( r.Len() <= 0 )
+        return 0;
 
-USHORT ScRange::ParseAny( const String& r, ScDocument* pDoc )
+	switch (rDetails.eConv)
+	{
+	default :
+	case ScAddress::CONV_OOO:
+		return lcl_ScRange_Parse_OOo( *this, r, pDoc );
+
+	case ScAddress::CONV_XL_A1:
+		return lcl_ScRange_Parse_XL_A1( *this, r.GetBuffer(), pDoc, FALSE );
+
+	case ScAddress::CONV_XL_R1C1:
+		return lcl_ScRange_Parse_XL_R1C1( *this, r.GetBuffer(), pDoc, rDetails, FALSE );
+	}
+}
+
+
+// Accept a full range, or an address
+USHORT ScRange::ParseAny( const String& r, ScDocument* pDoc,
+						  const ScAddress::Details& rDetails )
 {
-    USHORT nRet = Parse( r, pDoc );
+    USHORT nRet = Parse( r, pDoc, rDetails );
     const USHORT nValid = SCA_VALID | SCA_VALID_COL2 | SCA_VALID_ROW2 |
         SCA_VALID_TAB2;
+
     if ( (nRet & nValid) != nValid )
     {
         ScAddress aAdr;
-        nRet = aAdr.Parse( r, pDoc );
+        nRet = aAdr.Parse( r, pDoc, rDetails );
         if ( nRet & SCA_VALID )
             aStart = aEnd = aAdr;
     }
     return nRet;
 }
 
+// Parse only full row references
+USHORT ScRange::ParseCols( const String& rStr, ScDocument* pDoc,
+						   const ScAddress::Details& rDetails )
+{
+	const sal_Unicode* p = rStr.GetBuffer();
+	USHORT nRes = 0, ignored = 0;
+
+    if( NULL == p )
+        return 0;
+
+	pDoc = NULL; // make compiler shutup we may need this later
+
+	switch (rDetails.eConv)
+	{
+	default :
+	case ScAddress::CONV_OOO: // No full col refs in OOO yet, assume XL notation
+	case ScAddress::CONV_XL_A1:
+		if (NULL != (p = lcl_a1_get_col( p, &aStart, &ignored ) ) )
+		{
+			if( p[0] == ':')
+			{
+				if( NULL != (p = lcl_a1_get_col( p+1, &aEnd, &ignored )))
+				{
+					nRes = SCA_VALID_COL;
+				}
+			}
+			else
+			{
+				aEnd = aStart;
+				nRes = SCA_VALID_COL;
+			}
+		}
+		break;
+
+	case ScAddress::CONV_XL_R1C1:
+		if ((p[0] == 'C' || p[0] != 'c') &&
+			NULL != (p = lcl_r1c1_get_col( p, rDetails, &aStart, &ignored )))
+		{
+			if( p[0] == ':')
+			{
+				if( (p[1] == 'C' || p[1] == 'c') &&
+					NULL != (p = lcl_r1c1_get_col( p+1, rDetails, &aEnd, &ignored )))
+				{
+					nRes = SCA_VALID_COL;
+				}
+			}
+			else
+			{
+				aEnd = aStart;
+				nRes = SCA_VALID_COL;
+			}
+		}
+		break;
+	}
+
+	return (p != NULL && *p == '\0') ? nRes : 0;
+}
+
+// Parse only full row references
+USHORT ScRange::ParseRows( const String& rStr, ScDocument* pDoc,
+						   const ScAddress::Details& rDetails )
+{
+	const sal_Unicode* p = rStr.GetBuffer();
+	USHORT nRes = 0, ignored = 0;
+
+    if( NULL == p )
+        return 0;
+
+	pDoc = NULL; // make compiler shutup we may need this later
+
+	switch (rDetails.eConv)
+	{
+	default :
+	case ScAddress::CONV_OOO: // No full row refs in OOO yet, assume XL notation
+	case ScAddress::CONV_XL_A1:
+		if (NULL != (p = lcl_a1_get_row( p, &aStart, &ignored ) ) )
+		{
+			if( p[0] == ':')
+			{
+				if( NULL != (p = lcl_a1_get_row( p+1, &aEnd, &ignored )))
+				{
+					nRes = SCA_VALID_COL;
+				}
+			}
+			else
+			{
+				aEnd = aStart;
+				nRes = SCA_VALID_COL;
+			}
+		}
+		break;
+
+	case ScAddress::CONV_XL_R1C1:
+		if ((p[0] == 'R' || p[0] != 'r') &&
+			NULL != (p = lcl_r1c1_get_row( p, rDetails, &aStart, &ignored )))
+		{
+			if( p[0] == ':')
+			{
+				if( (p[1] == 'R' || p[1] == 'r') &&
+					NULL != (p = lcl_r1c1_get_row( p+1, rDetails, &aEnd, &ignored )))
+				{
+					nRes = SCA_VALID_COL;
+				}
+			}
+			else
+			{
+				aEnd = aStart;
+				nRes = SCA_VALID_COL;
+			}
+		}
+		break;
+	}
+
+	return (p != NULL && *p == '\0') ? nRes : 0;
+}
+
+static inline void
+lcl_a1_append_c ( String &r, int nCol, bool bIsAbs )
+{
+	if( bIsAbs )
+		r += '$';
+	ColToAlpha( r, nCol );
+}
+
+static inline void
+lcl_a1_append_r ( String &r, int nRow, bool bIsAbs )
+{
+	if ( bIsAbs )
+		r += '$';
+	r += String::CreateFromInt32( nRow+1 );
+}
+
+static inline void
+lcl_r1c1_append_c ( String &r, int nCol, bool bIsAbs,
+					const ScAddress::Details& rDetails )
+{
+	r += 'C';
+	if (bIsAbs)
+	{
+		r += String::CreateFromInt32( nCol + 1 );
+	}
+	else
+	{
+		nCol -= rDetails.nCol;
+		if (nCol != 0) {
+			r += '[';
+			r += String::CreateFromInt32( nCol );
+			r += ']';
+		}
+	}
+}
+static inline void
+lcl_r1c1_append_r ( String &r, int nRow, bool bIsAbs,
+					const ScAddress::Details& rDetails )
+{
+	r += 'R';
+	if (bIsAbs)
+	{
+		r += String::CreateFromInt32( nRow + 1 );
+	}
+	else
+	{
+		nRow -= rDetails.nRow;
+		if (nRow != 0) {
+			r += '[';
+			r += String::CreateFromInt32( nRow );
+			r += ']';
+		}
+	}
+}
 
-void ScAddress::Format( String& r, USHORT nFlags, ScDocument* pDoc ) const
+static String 
+getFileNameFromDoc( const ScDocument* pDoc )
+{
+	// TODO : er points at ScGlobal::GetAbsDocName()
+	// as a better template.  Look into it
+	String sFileName;
+	SfxObjectShell* pShell;
+
+	if( NULL != pDoc &&
+		NULL != (pShell = pDoc->GetDocumentShell() ) )
+	{
+		uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_QUERY );
+		if( xModel.is() )
+		{
+			if( xModel->getURL().getLength() )
+			{
+				INetURLObject aURL( xModel->getURL() );
+				sFileName = aURL.GetLastName();
+			}
+			else
+				sFileName = pShell->GetTitle();
+		}		
+	}
+#if 0
+		{
+			ByteString	aStr( sFileName, RTL_TEXTENCODING_UTF8 );
+			aStr.Append(static_cast< char >(0));
+			std::cerr << "docname \'" << aStr.GetBuffer() << '\'' << std::endl;
+		}
+#endif
+	return sFileName;
+}
+
+void ScAddress::Format( String& r, USHORT nFlags, ScDocument* pDoc,
+						const Details& rDetails) const
 {
     r.Erase();
     if( nFlags & SCA_VALID )
@@ -431,58 +1285,162 @@ void ScAddress::Format( String& r, USHOR
 //      if( nFlags & ( SCA_TAB_ABSOLUTE | SCA_TAB_3D ) )
         if( nFlags & SCA_TAB_3D )
         {
-            String aTabName;
+            String aTabName, aDocName;
             pDoc->GetName( nTab, aTabName );
-
             //  externe Referenzen (wie in ScCompiler::MakeTabStr)
-            String aDoc;
-            if ( aTabName.GetChar(0) == '\'' )
+            if( aTabName.GetChar(0) == '\'' )
             {   // "'Doc'#Tab"
                 xub_StrLen nPos, nLen = 1;
                 while( (nPos = aTabName.Search( '\'', nLen ))
                         != STRING_NOTFOUND )
                     nLen = nPos + 1;
-                if ( aTabName.GetChar(nLen) == SC_COMPILER_FILE_TAB_SEP )
+                if( aTabName.GetChar(nLen) == SC_COMPILER_FILE_TAB_SEP )
                 {
-                    aDoc = aTabName.Copy( 0, nLen + 1 );
+					aDocName = aTabName.Copy( 0, nLen + 1 );
                     aTabName.Erase( 0, nLen + 1 );
                 }
             }
-            r += aDoc;
+			else if( nFlags & SCA_FORCE_DOC )
+			{
+				// VBA has an 'external' flag that forces the addition of the
+				// tab name _and_ the doc name.  The VBA code would be
+				// needlessly complicated if it constructed an actual external
+				// reference so we add this somewhat cheesy kludge to force the
+				// addition of the document name even for non-external references
+				aDocName = getFileNameFromDoc( pDoc );
+			}
+			ScCompiler::CheckTabQuotes( aTabName, rDetails.eConv);
+
+			switch( rDetails.eConv )
+			{
+			default :
+			case CONV_OOO:
+				r += aDocName;
+				if( nFlags & SCA_TAB_ABSOLUTE )
+					r += '$';
+				r += aTabName;
+				r += '.';
+				break;
+
+			case CONV_XL_A1:
+			case CONV_XL_R1C1:
+				r += '[';
+				r += aDocName;
+				r += ']';
+				r += aTabName;
+				r += '!';
+				break;
+			}
+		}
+    }
+	switch( rDetails.eConv )
+	{
+	default :
+	case CONV_OOO:
+	case CONV_XL_A1:
+		if( nFlags & SCA_VALID_COL )
+			lcl_a1_append_c ( r, nCol, nFlags & SCA_COL_ABSOLUTE );
+		if( nFlags & SCA_VALID_ROW )
+			lcl_a1_append_r ( r, nRow, nFlags & SCA_ROW_ABSOLUTE );
+		break;
+
+	case CONV_XL_R1C1:
+		if( nFlags & SCA_VALID_ROW )
+			lcl_r1c1_append_r ( r, nRow, nFlags & SCA_ROW_ABSOLUTE, rDetails );
+		if( nFlags & SCA_VALID_COL )
+			lcl_r1c1_append_c ( r, nCol, nFlags & SCA_COL_ABSOLUTE, rDetails );
+		break;
+	}
+}
 
-            if( nFlags & SCA_TAB_ABSOLUTE )
-                r += '$';
-            ScCompiler::CheckTabQuotes( aTabName );
-            r += aTabName;
-            r += '.';
-        }
-    }
-    if( nFlags & SCA_VALID_COL )
-    {
-        if( nFlags & SCA_COL_ABSOLUTE )
-            r += '$';
-        ColToAlpha( r, nCol);
-    }
-    if( nFlags & SCA_VALID_ROW )
-    {
-        if ( nFlags & SCA_ROW_ABSOLUTE )
-            r += '$';
-        r += String::CreateFromInt32( Row()+1 );
-    }
+static void
+lcl_Split_DocTab( const ScDocument* pDoc,  SCTAB nTab,
+				  const ScAddress::Details& rDetails,
+				  USHORT nFlags,
+				  String& rTabName, String& rDocName )
+{
+	pDoc->GetName( nTab, rTabName );
+	rDocName.Erase();
+#if 0
+	{
+		ByteString	aStr(rTabName, RTL_TEXTENCODING_UTF8);
+		aStr.Append(static_cast< char >(0));
+		std::cerr << "tabname \'" << aStr.GetBuffer() << '\'' << std::endl;
+	}
+#endif
+	//  externe Referenzen (wie in ScCompiler::MakeTabStr)
+	if ( rTabName.GetChar(0) == '\'' )
+	{   // "'Doc'#Tab"
+		xub_StrLen nPos, nLen = 1;
+		while( (nPos = rTabName.Search( '\'', nLen )) != STRING_NOTFOUND )
+			nLen = nPos + 1;
+		if ( rTabName.GetChar(nLen) == SC_COMPILER_FILE_TAB_SEP )
+		{
+			rDocName = rTabName.Copy( 0, nLen + 1 );
+			rTabName.Erase( 0, nLen + 1 );
+		}
+    }
+	else if( nFlags & SCA_FORCE_DOC )
+	{
+		// VBA has an 'external' flag that forces the addition of the
+		// tab name _and_ the doc name.  The VBA code would be
+		// needlessly complicated if it constructed an actual external
+		// reference so we add this somewhat cheesy kludge to force the
+		// addition of the document name even for non-external references
+		rDocName = getFileNameFromDoc( pDoc );
+	}
+	ScCompiler::CheckTabQuotes( rTabName, rDetails.eConv);
 }
 
+static void
+lcl_ScRange_Format_XL_Header( String& r, const ScRange& rRange,
+							  USHORT nFlags, ScDocument* pDoc,
+							  const ScAddress::Details& rDetails )
+{
+	if( nFlags & SCA_TAB_3D )
+	{
+		String aTabName, aDocName;
+		lcl_Split_DocTab( pDoc, rRange.aStart.Tab(), rDetails, nFlags,
+						  aTabName, aDocName );
+		if( aDocName.Len() > 0 )
+		{
+			r += '[';
+			r += aDocName;
+			r += ']';
+		}
+		r += aTabName;
+
+		if( nFlags & SCA_TAB2_3D )
+		{
+			lcl_Split_DocTab( pDoc, rRange.aEnd.Tab(), rDetails, nFlags,
+							  aTabName, aDocName );
+			r += ':';
+			r += aTabName;
+		}
+		r += '!';
+	}
+}
 
-void ScRange::Format( String& r, USHORT nFlags, ScDocument* pDoc ) const
+void ScRange::Format( String& r, USHORT nFlags, ScDocument* pDoc,
+					  const ScAddress::Details& rDetails ) const
 {
     if( !( nFlags & SCA_VALID ) )
-        r = ScGlobal::GetRscString( STR_NOREF_STR );
-    else
     {
+        r = ScGlobal::GetRscString( STR_NOREF_STR );
+		return;
+	}
+
+#define	absrel_differ(nFlags, mask)	(((nFlags) & (mask)) ^ (((nFlags) >> 4) & (mask)))
+	switch( rDetails.eConv ) {
+	default :
+	case ScAddress::CONV_OOO: {
         BOOL bOneTab = (aStart.Tab() == aEnd.Tab());
         if ( !bOneTab )
             nFlags |= SCA_TAB_3D;
-        aStart.Format( r, nFlags, pDoc );
-        if( aStart != aEnd )
+		aStart.Format( r, nFlags, pDoc, rDetails );
+        if( aStart != aEnd ||
+			absrel_differ( nFlags, SCA_COL_ABSOLUTE ) ||
+			absrel_differ( nFlags, SCA_ROW_ABSOLUTE ))
         {
             String aName;
             nFlags = ( nFlags & SCA_VALID ) | ( ( nFlags >> 4 ) & 0x070F );
@@ -490,13 +1448,80 @@ void ScRange::Format( String& r, USHORT 
                 pDoc = NULL;
             else
                 nFlags |= SCA_TAB_3D;
-            aEnd.Format( aName, nFlags, pDoc );
+			aEnd.Format( aName, nFlags, pDoc, rDetails );
             r += ':';
             r += aName;
         }
     }
-}
+	break;
 
+	case ScAddress::CONV_XL_A1:
+		lcl_ScRange_Format_XL_Header( r, *this, nFlags, pDoc, rDetails );
+		if( aStart.Col() == 0 && aEnd.Col() >= MAXCOL )
+		{
+			// Full col refs always require 2 rows (2:2)
+			lcl_a1_append_r( r, aStart.Row(), nFlags & SCA_ROW_ABSOLUTE );
+			r += ':';
+			lcl_a1_append_r( r, aEnd.Row(), nFlags & SCA_ROW2_ABSOLUTE );
+		}
+		else if( aStart.Row() == 0 && aEnd.Row() >= MAXROW )
+		{
+			// Full row refs always require 2 cols (A:A)
+			lcl_a1_append_c( r, aStart.Col(), nFlags & SCA_COL_ABSOLUTE );
+			r += ':';
+			lcl_a1_append_c( r, aEnd.Col(), nFlags & SCA_COL2_ABSOLUTE );
+		}
+		else
+		{
+			lcl_a1_append_c ( r, aStart.Col(), nFlags & SCA_COL_ABSOLUTE );
+			lcl_a1_append_r ( r, aStart.Row(), nFlags & SCA_ROW_ABSOLUTE );
+			if( aStart.Col() != aEnd.Col() ||
+				absrel_differ( nFlags, SCA_COL_ABSOLUTE ) ||
+				aStart.Row() != aEnd.Row() ||
+				absrel_differ( nFlags, SCA_ROW_ABSOLUTE )) {
+				r += ':';
+				lcl_a1_append_c ( r, aEnd.Col(), nFlags & SCA_COL2_ABSOLUTE );
+				lcl_a1_append_r ( r, aEnd.Row(), nFlags & SCA_ROW2_ABSOLUTE );
+			}
+		}
+	break;
+
+	case ScAddress::CONV_XL_R1C1:
+		lcl_ScRange_Format_XL_Header( r, *this, nFlags, pDoc, rDetails );
+		if( aStart.Col() == 0 && aEnd.Col() >= MAXCOL )
+		{
+			lcl_r1c1_append_r( r, aStart.Row(), nFlags & SCA_ROW_ABSOLUTE, rDetails );
+			if( aStart.Row() != aEnd.Row() ||
+				absrel_differ( nFlags, SCA_ROW_ABSOLUTE )) {
+				r += ':';
+				lcl_r1c1_append_r( r, aEnd.Row(), nFlags & SCA_ROW2_ABSOLUTE, rDetails );
+			}
+		}
+		else if( aStart.Row() == 0 && aEnd.Row() >= MAXROW )
+		{
+			lcl_r1c1_append_c( r, aStart.Col(), nFlags & SCA_COL_ABSOLUTE, rDetails );
+			if( aStart.Col() != aEnd.Col() ||
+				absrel_differ( nFlags, SCA_COL_ABSOLUTE )) {
+				r += ':';
+				lcl_r1c1_append_c( r, aEnd.Col(), nFlags & SCA_COL2_ABSOLUTE, rDetails );
+			}
+		}
+		else
+		{
+			lcl_r1c1_append_r( r, aStart.Row(), nFlags & SCA_ROW_ABSOLUTE, rDetails );
+			lcl_r1c1_append_c( r, aStart.Col(), nFlags & SCA_COL_ABSOLUTE, rDetails );
+			if( aStart.Col() != aEnd.Col() ||
+				absrel_differ( nFlags, SCA_COL_ABSOLUTE ) ||
+				aStart.Row() != aEnd.Row() ||
+				absrel_differ( nFlags, SCA_ROW_ABSOLUTE )) {
+				r += ':';
+				lcl_r1c1_append_r( r, aEnd.Row(), nFlags & SCA_ROW2_ABSOLUTE, rDetails );
+				lcl_r1c1_append_c( r, aEnd.Col(), nFlags & SCA_COL2_ABSOLUTE, rDetails );
+			}
+		}
+	}
+#undef	absrel_differ
+}
 
 bool ScAddress::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* pDoc )
 {
@@ -544,9 +1569,16 @@ String ScAddress::GetText() const
 }
 
 
-String ScAddress::GetColRowString( bool bAbsolute ) const
+String ScAddress::GetColRowString( bool bAbsolute,
+								   const Details& rDetails ) const
 {
     String aString;
+
+	switch( rDetails.eConv )
+	{
+	default :
+	case ScAddress::CONV_OOO:
+	case ScAddress::CONV_XL_A1:
     if (bAbsolute)
         aString.Append( '$' );
 
@@ -556,12 +1588,20 @@ String ScAddress::GetColRowString( bool 
         aString.Append( '$' );
 
     aString += String::CreateFromInt32(nRow+1);
+		break;
+
+	case ScAddress::CONV_XL_R1C1:
+		lcl_r1c1_append_r ( aString, nRow, bAbsolute, rDetails );
+		lcl_r1c1_append_c ( aString, nCol, bAbsolute, rDetails );
+		break;
+	}
 
     return aString;
 }
 
 
-String ScRefAddress::GetRefString( ScDocument* pDoc, SCTAB nActTab) const
+String ScRefAddress::GetRefString( ScDocument* pDoc, SCTAB nActTab,
+								   const ScAddress::Details& rDetails ) const
 {
     if ( !pDoc )
         return EMPTY_STRING;
@@ -581,7 +1621,7 @@ String ScRefAddress::GetRefString( ScDoc
     if ( !bRelRow )
         nFlags |= SCA_ROW_ABSOLUTE;
 
-    aAdr.Format( aString, nFlags, pDoc );
+    aAdr.Format( aString, nFlags, pDoc, rDetails );
 
     return aString;
 }
diff -r -u -p sc/source/core/tool/chgtrack.cxx sc/source/core/tool/chgtrack.cxx
--- sc/source/core/tool/chgtrack.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/tool/chgtrack.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -1936,7 +1936,7 @@ void ScChangeActionContent::SetValueStri
 	{
 		rValue.Erase();
 		pCell = new ScFormulaCell(
-			pDoc, aBigRange.aStart.MakeAddress(), rStr );
+			pDoc, aBigRange.aStart.MakeAddress(), rStr, ScAddress::CONV_OOO );
 		((ScFormulaCell*)pCell)->SetInChangeTrack( TRUE );
 	}
 	else
diff -r -u -p sc/source/core/tool/compiler.cxx sc/source/core/tool/compiler.cxx
--- sc/source/core/tool/compiler.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/tool/compiler.cxx	2006-09-05 12:50:16.000000000 -0400
@@ -86,10 +86,10 @@
 String* ScCompiler::pSymbolTableNative = NULL;
 String* ScCompiler::pSymbolTableEnglish = NULL;
 USHORT  ScCompiler::nAnzStrings = 0;
-ULONG* ScCompiler::pCharTable = 0;
 ScOpCodeHashMap* ScCompiler::pSymbolHashMapNative = NULL;
 ScOpCodeHashMap* ScCompiler::pSymbolHashMapEnglish = NULL;
 CharClass* ScCompiler::pCharClassEnglish = NULL;
+const ScCompiler::Convention* ScCompiler::pConventions[ ] = { NULL, NULL, NULL };
 
 enum ScanState
 {
@@ -110,7 +110,7 @@ struct ScArrayStack
 
 static sal_Char* pInternal[ 5 ] = { "GAME", "SPEW", "TTT", "STARCALCTEAM", "ANTWORT" };
 
-
+using namespace ::com::sun::star::i18n;
 /////////////////////////////////////////////////////////////////////////
 
 short lcl_GetRetFormat( OpCode eOpCode )
@@ -222,56 +222,14 @@ public:
 
 void ScCompiler::Init()
 {
+    if (NULL != pSymbolTableNative)
+		return;
+
     pSymbolTableNative = new String[SC_OPCODE_LAST_OPCODE_ID+1];
     pSymbolHashMapNative = new ScOpCodeHashMap( SC_OPCODE_LAST_OPCODE_ID+1 );
     ScOpCodeList aOpCodeListNative( RID_SC_FUNCTION_NAMES, pSymbolTableNative,
             *pSymbolHashMapNative );
     nAnzStrings = SC_OPCODE_LAST_OPCODE_ID+1;
-
-    pCharTable = new ULONG [128];
-    USHORT i;
-    for (i = 0; i < 128; i++)
-        pCharTable[i] = SC_COMPILER_C_ILLEGAL;
-    /*   */     pCharTable[32] = SC_COMPILER_C_CHAR_DONTCARE | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* ! */     pCharTable[33] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* " */     pCharTable[34] = SC_COMPILER_C_CHAR_STRING | SC_COMPILER_C_STRING_SEP;
-    /* # */     pCharTable[35] = SC_COMPILER_C_WORD_SEP;
-    /* $ */     pCharTable[36] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
-    /* % */     pCharTable[37] = SC_COMPILER_C_VALUE;
-    /* & */     pCharTable[38] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* ' */     pCharTable[39] = SC_COMPILER_C_NAME_SEP;
-    /* ( */     pCharTable[40] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* ) */     pCharTable[41] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* * */     pCharTable[42] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* + */     pCharTable[43] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN;
-    /* , */     pCharTable[44] = SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE;
-    /* - */     pCharTable[45] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN;
-    /* . */     pCharTable[46] = SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE | SC_COMPILER_C_IDENT;
-    /* / */     pCharTable[47] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    for (i = 48; i < 58; i++)
-    /* 0-9 */   pCharTable[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;
-    /* : */     pCharTable[58] = SC_COMPILER_C_WORD | SC_COMPILER_C_IDENT;
-    /* ; */     pCharTable[59] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* < */     pCharTable[60] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* = */     pCharTable[61] = SC_COMPILER_C_CHAR | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* > */     pCharTable[62] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* ? */     pCharTable[63] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD;
-    /* @ */     // FREI
-    for (i = 65; i < 91; i++)
-    /* A-Z */   pCharTable[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
-    /* [ */     // FREI
-    /* \ */     // FREI
-    /* ] */     // FREI
-    /* ^ */     pCharTable[94] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
-    /* _ */     pCharTable[95] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
-    /* ` */     // FREI
-    for (i = 97; i < 123; i++)
-    /* a-z */   pCharTable[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT;
-    /* { */     // FREI
-    /* | */     // FREI
-    /* } */     // FREI
-    /* ~ */     // FREI
-    /* 127 */   // FREI
 }
 
 void ScCompiler::DeInit()
@@ -303,8 +261,6 @@ void ScCompiler::DeInit()
         delete pCharClassEnglish;
         pCharClassEnglish = NULL;
     }
-    delete [] pCharTable;
-    pCharTable = NULL;
 }
 
 void ScCompiler::SetCompileEnglish( BOOL bCompileEnglish )
@@ -341,54 +297,137 @@ void ScCompiler::SetCompileEnglish( BOOL
 
 //-----------------------------------------------------------------------------
 
-ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,
-                        const ScTokenArray& rArr )
-        :
-        aPos( rPos ),
-        pSymbolTable( pSymbolTableNative ),
-        pSymbolHashMap( pSymbolHashMapNative ),
-        pCharClass( ScGlobal::pCharClass ),
-        nRecursion(0),
-        bAutoCorrect( FALSE ),
-        bCorrected( FALSE ),
-        bCompileForFAP( FALSE ),
-        bIgnoreErrors( FALSE ),
-        bCompileXML( FALSE ),
-        bImportXML ( FALSE )
+ScCompiler::Convention::~Convention()
 {
-    if (!nAnzStrings)
-        Init();
-    pArr = (ScTokenArray*) &rArr;
-    pDoc = pDocument;
-    nMaxTab = pDoc->GetTableCount() - 1;
-    pStack = NULL;
-    nNumFmt = NUMBERFORMAT_UNDEFINED;
+	delete [] mpCharTable;
+	mpCharTable = NULL;
 }
 
-ScCompiler::ScCompiler(ScDocument* pDocument, const ScAddress& rPos )
+ScCompiler::Convention::Convention( ScAddress::Convention eConv )
         :
-        aPos( rPos ),
-        pSymbolTable( pSymbolTableNative ),
-        pSymbolHashMap( pSymbolHashMapNative ),
-        pCharClass( ScGlobal::pCharClass ),
-        nRecursion(0),
-        bAutoCorrect( FALSE ),
-        bCorrected( FALSE ),
-        bCompileForFAP( FALSE ),
-        bIgnoreErrors( FALSE ),
-        bCompileXML( FALSE ),
-        bImportXML ( FALSE )
+	meConv( eConv )
 {
-    if (!nAnzStrings)
-        Init();
-    pDoc = pDocument;
-    nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
-    pStack = NULL;
-    nNumFmt = NUMBERFORMAT_UNDEFINED;
+    int i;
+	ULONG *t= new ULONG [128];
+
+	ScCompiler::pConventions[ meConv ] = this;
+	mpCharTable = t;
+
+	for (i = 0; i < 128; i++)
+		t[i] = SC_COMPILER_C_ILLEGAL;
+
+/*   */     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;
+/* " */     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;
+/* % */     t[37] = SC_COMPILER_C_VALUE;
+/* & */     t[38] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* ' */     t[39] = SC_COMPILER_C_NAME_SEP;
+/* ( */     t[40] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* ) */     t[41] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* * */     t[42] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* + */     t[43] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN;
+/* , */     t[44] = SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE;
+/* - */     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++)
+/* 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_WORD | SC_COMPILER_C_IDENT;
+/* ; */     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;
+/* = */     t[61] = SC_COMPILER_C_CHAR | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+/* > */     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;
+/* @ */     // FREI
+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;
+/* [ */     // FREI
+/* \ */     // FREI
+/* ] */     // FREI
+/* ^ */     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;
+/* ` */     // FREI
+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;
+/* { */     // FREI
+/* | */     // FREI
+/* } */     // FREI
+/* ~ */     // FREI
+/* 127 */   // FREI
+	if( ScAddress::CONV_XL_A1 == meConv || ScAddress::CONV_XL_R1C1 == meConv )
+	{
+/*   */     t[32] |=   SC_COMPILER_C_WORD;
+/* ! */     t[33] |=   SC_COMPILER_C_IDENT | SC_COMPILER_C_WORD;
+/* " */     t[34] |=   SC_COMPILER_C_WORD;
+/* # */     t[35] &= (~SC_COMPILER_C_WORD_SEP);
+/* # */     t[35] |=   SC_COMPILER_C_WORD;
+/* % */     t[37] |=   SC_COMPILER_C_WORD;
+/* ' */     t[39] |=   SC_COMPILER_C_WORD;
+
+/* % */     t[37] |=   SC_COMPILER_C_WORD;
+/* & */     t[38] |=   SC_COMPILER_C_WORD;
+/* ' */     t[39] |=   SC_COMPILER_C_WORD;
+/* ( */     t[40] |=   SC_COMPILER_C_WORD;
+/* ) */     t[41] |=   SC_COMPILER_C_WORD;
+/* * */     t[42] |=   SC_COMPILER_C_WORD;
+/* + */     t[43] |=   SC_COMPILER_C_WORD;
+#if 0 /* this really needs to be locale specific. */
+/* , */     t[44]  =   SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP;
+#else
+/* , */     t[44] |=   SC_COMPILER_C_WORD;
+#endif
+/* - */     t[45] |=   SC_COMPILER_C_WORD;
+
+/* ; */     t[59] |=   SC_COMPILER_C_WORD;
+/* < */     t[60] |=   SC_COMPILER_C_WORD;
+/* = */     t[61] |=   SC_COMPILER_C_WORD;
+/* > */     t[62] |=   SC_COMPILER_C_WORD;
+/* ? */     // question really is not permitted in sheet name
+/* @ */     t[64] |=   SC_COMPILER_C_WORD;
+/* [ */     t[91] |=   SC_COMPILER_C_WORD;
+/* ] */     t[93] |=   SC_COMPILER_C_WORD;
+/* { */     t[123]|=   SC_COMPILER_C_WORD;
+/* | */     t[124]|=   SC_COMPILER_C_WORD;
+/* } */     t[124]|=   SC_COMPILER_C_WORD;
+/* ~ */     t[126]|=   SC_COMPILER_C_WORD;
+
+		if( ScAddress::CONV_XL_R1C1 == meConv )
+		{
+		/* - */     t[45] |= SC_COMPILER_C_IDENT;
+		/* [ */     t[91] |= SC_COMPILER_C_IDENT;
+		/* ] */     t[93] |= SC_COMPILER_C_IDENT;
+		}
+	}
 }
 
+//-----------------------------------------------------------------------------
+
+struct Convention_A1 : public ScCompiler::Convention
+{
+	Convention_A1( ScAddress::Convention eConv ) : ScCompiler::Convention( eConv ) { }
+	static String MakeColStr( SCCOL nCol );
+	static void MakeColStr( rtl::OUStringBuffer& rBuffer, SCCOL nCol );
+	static String MakeRowStr( SCROW nRow );
+	static void MakeRowStr( rtl::OUStringBuffer& rBuffer, SCROW nRow );
+
+	ParseResult parseAnyToken( const String& rFormula,
+							   xub_StrLen nSrcPos,
+							   const CharClass* pCharClass) const
+	{
+        static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
+            KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR;
+        static const sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT |
+            KParseTokens::ASC_COLON;
+        // '?' allowed in range names because of Xcl :-/
+        static const String aAddAllowed( '?' );
+		return pCharClass->parseAnyToken( rFormula,
+                nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
+	}
+};
 
-String ScCompiler::MakeColStr( SCCOL nCol )
+String Convention_A1::MakeColStr( SCCOL nCol )
 {
     if ( !ValidCol( nCol) )
         return ScGlobal::GetRscString(STR_NO_REF_TABLE);
@@ -396,7 +435,7 @@ String ScCompiler::MakeColStr( SCCOL nCo
         return ::ColToAlpha( nCol);
 }
 
-void ScCompiler::MakeColStr( rtl::OUStringBuffer& rBuffer, SCCOL nCol )
+void Convention_A1::MakeColStr( rtl::OUStringBuffer& rBuffer, SCCOL nCol )
 {
     if ( !ValidCol( nCol) )
         rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
@@ -404,7 +443,7 @@ void ScCompiler::MakeColStr( rtl::OUStri
         ::ColToAlpha( rBuffer, nCol);
 }
 
-String ScCompiler::MakeRowStr( SCROW nRow )
+String Convention_A1::MakeRowStr( SCROW nRow )
 {
     if ( !ValidRow(nRow) )
         return ScGlobal::GetRscString(STR_NO_REF_TABLE);
@@ -412,7 +451,7 @@ String ScCompiler::MakeRowStr( SCROW nRo
         return String::CreateFromInt32( nRow + 1 );
 }
 
-void ScCompiler::MakeRowStr( rtl::OUStringBuffer& rBuffer, SCROW nRow )
+void Convention_A1::MakeRowStr( rtl::OUStringBuffer& rBuffer, SCROW nRow )
 {
     if ( !ValidRow(nRow) )
         rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
@@ -420,10 +459,15 @@ void ScCompiler::MakeRowStr( rtl::OUStri
         rBuffer.append(sal_Int32(nRow + 1));
 }
 
-String ScCompiler::MakeTabStr( SCTAB nTab, String& aDoc )
+//-----------------------------------------------------------------------------
+
+struct ConventionOOO_A1 : public Convention_A1
+{
+	ConventionOOO_A1() : Convention_A1 (ScAddress::CONV_OOO) { }
+	static String MakeTabStr( const ScCompiler& rComp, SCTAB nTab, String& aDoc )
 {
     String aString;
-    if (!pDoc->GetName(nTab, aString))
+		if (!rComp.pDoc->GetName( nTab, aString ))
         aString = ScGlobal::GetRscString(STR_NO_REF_TABLE);
     else
     {
@@ -444,43 +488,106 @@ String ScCompiler::MakeTabStr( SCTAB nTa
         }
         else
             aDoc.Erase();
-        CheckTabQuotes( aString );
+			ScCompiler::CheckTabQuotes( aString, ScAddress::CONV_OOO );
     }
     aString += '.';
     return aString;
 }
 
-void ScCompiler::CheckTabQuotes( String& rString )
-{
-    register const sal_Unicode* p = rString.GetBuffer();
-    register const sal_Unicode* const pEnd = p + rString.Len();
-    while ( p < pEnd )
-    {
-        if( !IsWordChar( *p ) )
-        {
-            rString.Insert( '\'', 0 );
-            rString += '\'';
-            return ;
-        }
-        p++;
-    }
-    if ( CharClass::isAsciiNumeric( rString ) )
-    {
-        rString.Insert( '\'', 0 );
-        rString += '\'';
-    }
+	void MakeRefStr( rtl::OUStringBuffer&	rBuffer,
+					 const ScCompiler&		rComp,
+					 const ComplRefData& rRef,
+					 BOOL bSingleRef ) const
+{
+		ComplRefData aRef( rRef );
+		// In case absolute/relative positions weren't separately available:
+		// transform relative to absolute!
+		//  AdjustReference( aRef.Ref1 );
+		//  if( !bSingleRef )
+		//      AdjustReference( aRef.Ref2 );
+		aRef.Ref1.CalcAbsIfRel( rComp.aPos );
+		if( !bSingleRef )
+			aRef.Ref2.CalcAbsIfRel( rComp.aPos );
+		if( aRef.Ref1.IsFlag3D() )
+    {
+			if (aRef.Ref1.IsTabDeleted())
+        {
+				if (!aRef.Ref1.IsTabRel())
+					rBuffer.append(sal_Unicode('$'));
+				rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+				rBuffer.append(sal_Unicode('.'));
+    }
+			else
+    {
+				String aDoc;
+				String aRefStr( MakeTabStr( rComp, aRef.Ref1.nTab, aDoc ) );
+				rBuffer.append(aDoc);
+				if (!aRef.Ref1.IsTabRel()) rBuffer.append(sal_Unicode('$'));
+				rBuffer.append(aRefStr);
+    }
+}
+		if (!aRef.Ref1.IsColRel())
+			rBuffer.append(sal_Unicode('$'));
+		if ( aRef.Ref1.IsColDeleted() )
+			rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+		else
+			MakeColStr(rBuffer, aRef.Ref1.nCol );
+		if (!aRef.Ref1.IsRowRel())
+			rBuffer.append(sal_Unicode('$'));
+		if ( aRef.Ref1.IsRowDeleted() )
+			rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+		else
+			MakeRowStr( rBuffer, aRef.Ref1.nRow );
+		if (!bSingleRef)
+{
+			rBuffer.append(sal_Unicode(':'));
+			if (aRef.Ref2.IsFlag3D() || aRef.Ref2.nTab != aRef.Ref1.nTab)
+			{
+				if (aRef.Ref2.IsTabDeleted())
+				{
+					if (!aRef.Ref2.IsTabRel())
+						rBuffer.append(sal_Unicode('$'));
+					rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+					rBuffer.append(sal_Unicode('.'));
+				}
+				else
+				{
+					String aDoc;
+					String aRefStr( MakeTabStr( rComp, aRef.Ref2.nTab, aDoc ) );
+					rBuffer.append(aDoc);
+					if (!aRef.Ref2.IsTabRel()) rBuffer.append(sal_Unicode('$'));
+					rBuffer.append(aRefStr);
+				}
+			}
+			if (!aRef.Ref2.IsColRel())
+				rBuffer.append(sal_Unicode('$'));
+			if ( aRef.Ref2.IsColDeleted() )
+				rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+			else
+				MakeColStr( rBuffer, aRef.Ref2.nCol );
+			if (!aRef.Ref2.IsRowRel())
+				rBuffer.append(sal_Unicode('$'));
+			if ( aRef.Ref2.IsRowDeleted() )
+				rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+			else
+				MakeRowStr( rBuffer, aRef.Ref2.nRow );
 }
+	}
+};
 
-String ScCompiler::MakeRefStr( ComplRefData& rRef, BOOL bSingleRef )
-{
-    rtl::OUStringBuffer aBuffer;
-    MakeRefStr( aBuffer, rRef, bSingleRef );
-    return String( aBuffer );
-}
 
-void ScCompiler::MakeRefStr( rtl::OUStringBuffer& rBuffer, ComplRefData& rRef, BOOL bSingleRef )
+static const ConventionOOO_A1 ConvOOO_A1;
+const ScCompiler::Convention *pConvOOO_A1 = &ConvOOO_A1;
+
+//-----------------------------------------------------------------------------
+
+struct ConventionOOO_A1_XML : public ConventionOOO_A1
+{
+	void MakeRefStr( rtl::OUStringBuffer&	rBuffer,
+					 const ScCompiler&		rComp,
+					 const ComplRefData& rRef,
+					 BOOL bSingleRef ) const
 {
-    if (bCompileXML)
         rBuffer.append(sal_Unicode('['));
     ComplRefData aRef( rRef );
     // In case absolute/relative positions weren't separately available:
@@ -488,9 +595,9 @@ void ScCompiler::MakeRefStr( rtl::OUStri
 //  AdjustReference( aRef.Ref1 );
 //  if( !bSingleRef )
 //      AdjustReference( aRef.Ref2 );
-    aRef.Ref1.CalcAbsIfRel( aPos );
+			aRef.Ref1.CalcAbsIfRel( rComp.aPos );
     if( !bSingleRef )
-        aRef.Ref2.CalcAbsIfRel( aPos );
+				aRef.Ref2.CalcAbsIfRel( rComp.aPos );
     if( aRef.Ref1.IsFlag3D() )
     {
         if (aRef.Ref1.IsTabDeleted())
@@ -503,13 +610,13 @@ void ScCompiler::MakeRefStr( rtl::OUStri
         else
         {
             String aDoc;
-            String aRefStr( MakeTabStr( aRef.Ref1.nTab, aDoc ) );
+					String aRefStr( MakeTabStr( rComp, aRef.Ref1.nTab, aDoc ) );
             rBuffer.append(aDoc);
             if (!aRef.Ref1.IsTabRel()) rBuffer.append(sal_Unicode('$'));
             rBuffer.append(aRefStr);
         }
     }
-    else if (bCompileXML)
+			else
         rBuffer.append(sal_Unicode('.'));
     if (!aRef.Ref1.IsColRel())
         rBuffer.append(sal_Unicode('$'));
@@ -538,13 +645,13 @@ void ScCompiler::MakeRefStr( rtl::OUStri
             else
             {
                 String aDoc;
-                String aRefStr( MakeTabStr( aRef.Ref2.nTab, aDoc ) );
+						String aRefStr( MakeTabStr( rComp, aRef.Ref2.nTab, aDoc ) );
                 rBuffer.append(aDoc);
                 if (!aRef.Ref2.IsTabRel()) rBuffer.append(sal_Unicode('$'));
                 rBuffer.append(aRefStr);
             }
         }
-        else if (bCompileXML)
+				else
             rBuffer.append(sal_Unicode('.'));
         if (!aRef.Ref2.IsColRel())
             rBuffer.append(sal_Unicode('$'));
@@ -559,12 +666,423 @@ void ScCompiler::MakeRefStr( rtl::OUStri
         else
             MakeRowStr( rBuffer, aRef.Ref2.nRow );
     }
-    if (bCompileXML)
         rBuffer.append(sal_Unicode(']'));
 }
+};
+
+static const ConventionOOO_A1_XML ConvOOO_A1_XML;
+static const ScCompiler::Convention *pConvOOO_A1_XML = &ConvOOO_A1_XML;
+
+//-----------------------------------------------------------------------------
+
+struct ConventionXL
+{
+	static bool GetDocAndTab( const ScCompiler& rComp,
+							  const SingleRefData& rRef,
+							  String& rDocName,
+							  String& rTabName )
+	{
+		bool bHasDoc = false;
+
+		rDocName.Erase();
+		if (rRef.IsTabDeleted() ||
+			!rComp.pDoc->GetName( rRef.nTab, rTabName ))
+		{
+			rTabName = ScGlobal::GetRscString( STR_NO_REF_TABLE );
+			return false;
+		}
+
+		// Cheesy hack to unparse the OOO style "'Doc'#Tab"
+		if ( rTabName.GetChar(0) == '\'' )
+		{
+			xub_StrLen nPos, nLen = 1;
+
+			while( (nPos = rTabName.Search( '\'', nLen )) != STRING_NOTFOUND )
+				nLen = nPos + 1;
+
+			if ( rTabName.GetChar(nLen) == SC_COMPILER_FILE_TAB_SEP )
+			{
+				rDocName = rTabName.Copy( 0, nLen );
+				// TODO : More research into how XL escapes the doc path
+				rDocName = INetURLObject::decode( rDocName, INET_HEX_ESCAPE,
+					INetURLObject::DECODE_UNAMBIGUOUS );
+				rTabName.Erase( 0, nLen + 1 );
+				bHasDoc = true;
+			}
+		}
+
+		// XL uses the same sheet name quoting conventions in both modes
+		// it is safe to use A1 here
+		ScCompiler::CheckTabQuotes( rTabName, ScAddress::CONV_XL_A1 );
+		return bHasDoc;
+	}
+
+	static void MakeDocStr( rtl::OUStringBuffer& rBuf,
+							const ScCompiler& rComp,
+							const ComplRefData& rRef,
+							bool bSingleRef )
+	{
+		if( rRef.Ref1.IsFlag3D() )
+		{
+			String aStartTabName, aStartDocName, aEndTabName, aEndDocName;
+			bool bStartHasDoc = false, bEndHasDoc = false;
+
+			bStartHasDoc = GetDocAndTab( rComp, rRef.Ref1,
+										 aStartDocName, aStartTabName);
+
+			if( !bSingleRef && rRef.Ref2.IsFlag3D() )
+			{
+				bEndHasDoc = GetDocAndTab( rComp, rRef.Ref2,
+										   aEndDocName, aEndTabName);
+			}
+			else
+				bEndHasDoc = bStartHasDoc;
+
+			if( bStartHasDoc )
+			{
+				// A ref across multipled workbooks ?
+				if( !bEndHasDoc )
+					return;
+
+				rBuf.append( sal_Unicode( '[' ) );
+				rBuf.append( aStartDocName );
+				rBuf.append( sal_Unicode( ']' ) );
+			}
+
+			rBuf.append( aStartTabName );
+			if( !bSingleRef && aStartTabName != aEndTabName )
+			{
+				rBuf.append( sal_Unicode( ':' ) );
+				rBuf.append( aEndTabName );
+			}
+
+			rBuf.append( sal_Unicode( '!' ) );
+		}
+	}
+};
+
+struct ConventionXL_A1 : public Convention_A1, public ConventionXL
+{
+	ConventionXL_A1() : Convention_A1( ScAddress::CONV_XL_A1 ) { }
+	void MakeRefStr( rtl::OUStringBuffer&	rBuf,
+					 const ScCompiler&		rComp,
+					 const ComplRefData& rRef,
+					 BOOL bSingleRef ) const
+	{
+		ComplRefData aRef( rRef );
+
+		MakeDocStr( rBuf, rComp, aRef, bSingleRef );
+
+		// Play fast and loose with invalid refs.  There is not much point in producing
+		// Foo!A1:#REF! versus #REF! at this point
+		aRef.Ref1.CalcAbsIfRel( rComp.aPos );
+		if( aRef.Ref1.IsColDeleted() || aRef.Ref1.IsRowDeleted() )
+		{
+			rBuf.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+			return;
+		}
+
+		if( !bSingleRef )
+		{
+			aRef.Ref2.CalcAbsIfRel( rComp.aPos );
+			if( aRef.Ref2.IsColDeleted() || aRef.Ref2.IsRowDeleted() )
+			{
+				rBuf.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+				return;
+			}
+
+			if( aRef.Ref1.nCol == 0 && aRef.Ref2.nCol >= MAXCOL )
+			{
+				if (!aRef.Ref1.IsRowRel())
+					rBuf.append(sal_Unicode( '$' ));
+				MakeRowStr( rBuf, aRef.Ref1.nRow );
+				rBuf.append(sal_Unicode( ':' ));
+				if (!aRef.Ref2.IsRowRel())
+					rBuf.append(sal_Unicode( '$' ));
+				MakeRowStr( rBuf, aRef.Ref2.nRow );
+				return;
+			} 
+
+			if( aRef.Ref1.nRow == 0 && aRef.Ref2.nRow >= MAXROW )
+			{
+				if (!aRef.Ref1.IsColRel())
+					rBuf.append(sal_Unicode( '$' ));
+				MakeColStr(rBuf, aRef.Ref1.nCol );
+				rBuf.append(sal_Unicode( ':' ));
+				if (!aRef.Ref2.IsColRel())
+					rBuf.append(sal_Unicode( '$' ));
+				MakeColStr(rBuf, aRef.Ref2.nCol );
+				return;
+			}
+		}
+
+		if (!aRef.Ref1.IsColRel())
+			rBuf.append(sal_Unicode('$'));
+		MakeColStr(rBuf, aRef.Ref1.nCol );
+		if (!aRef.Ref1.IsRowRel())
+			rBuf.append(sal_Unicode('$'));
+		MakeRowStr( rBuf, aRef.Ref1.nRow );
+
+		if (!bSingleRef)
+		{
+			rBuf.append(sal_Unicode( ':' ));
+			if (!aRef.Ref2.IsColRel())
+				rBuf.append(sal_Unicode('$'));
+			MakeColStr(rBuf, aRef.Ref2.nCol );
+			if (!aRef.Ref2.IsRowRel())
+				rBuf.append(sal_Unicode('$'));
+			MakeRowStr( rBuf, aRef.Ref2.nRow );
+		}
+	}
+};
+
+static const ConventionXL_A1 ConvXL_A1;
+static const ScCompiler::Convention *pConvXL_A1 = &ConvXL_A1;
+
+//-----------------------------------------------------------------------------
+
+static void
+r1c1_add_col( rtl::OUStringBuffer &rBuf, const SingleRefData& rRef )
+{
+	rBuf.append( sal_Unicode( 'C' ) );
+	if( rRef.IsColRel() )
+	{
+		if (rRef.nRelCol != 0)
+		{
+			rBuf.append( sal_Unicode( '[' ) );
+			rBuf.append( String::CreateFromInt32( rRef.nRelCol ) );
+			rBuf.append( sal_Unicode( ']' ) );
+		}
+	}
+	else
+		rBuf.append( String::CreateFromInt32( rRef.nCol + 1 ) );
+}
+static void
+r1c1_add_row( rtl::OUStringBuffer &rBuf, const SingleRefData& rRef )
+{
+	rBuf.append( sal_Unicode( 'R' ) );
+	if( rRef.IsRowRel() )
+	{
+		if (rRef.nRelRow != 0)
+		{
+			rBuf.append( sal_Unicode( '[' ) );
+			rBuf.append( String::CreateFromInt32( rRef.nRelRow ) );
+			rBuf.append( sal_Unicode( ']' ) );
+		}
+	}
+	else
+		rBuf.append( String::CreateFromInt32( rRef.nRow + 1 ) );
+}
+
+struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
+{
+	ConventionXL_R1C1() : ScCompiler::Convention( ScAddress::CONV_XL_R1C1 ) { }
+	void MakeRefStr( rtl::OUStringBuffer&	rBuf,
+					 const ScCompiler&		rComp,
+					 const ComplRefData& rRef,
+					 BOOL bSingleRef ) const
+	{
+		ComplRefData aRef( rRef );
+
+		MakeDocStr( rBuf, rComp, aRef, bSingleRef );
+
+		// Play fast and loose with invalid refs.  There is not much point in producing
+		// Foo!A1:#REF! versus #REF! at this point
+		aRef.Ref1.CalcAbsIfRel( rComp.aPos );
+		if( aRef.Ref1.IsColDeleted() || aRef.Ref1.IsRowDeleted() )
+		{
+			rBuf.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+			return;
+		}
+
+		if( !bSingleRef )
+		{
+			aRef.Ref2.CalcAbsIfRel( rComp.aPos );
+			if( aRef.Ref2.IsColDeleted() || aRef.Ref2.IsRowDeleted() )
+			{
+				rBuf.append(ScGlobal::GetRscString(STR_NO_REF_TABLE));
+				return;
+			}
+
+			if( aRef.Ref1.nCol == 0 && aRef.Ref2.nCol >= MAXCOL )
+			{
+				r1c1_add_row( rBuf,  rRef.Ref1 );
+				if( rRef.Ref1.nRow != rRef.Ref2.nRow ||
+					rRef.Ref1.IsRowRel() != rRef.Ref2.IsRowRel() ) {
+					rBuf.append (sal_Unicode ( ':' ) );
+					r1c1_add_row( rBuf,  rRef.Ref2 );
+				}
+				return;
+
+			}
+
+			if( aRef.Ref1.nRow == 0 && aRef.Ref2.nRow >= MAXROW )
+			{
+				r1c1_add_col( rBuf, rRef.Ref1 );
+				if( rRef.Ref1.nCol != rRef.Ref2.nCol ||
+					rRef.Ref1.IsColRel() != rRef.Ref2.IsColRel() )
+				{
+					rBuf.append (sal_Unicode ( ':' ) );
+					r1c1_add_col( rBuf,  rRef.Ref2 );
+				}
+				return;
+			}
+		}
+
+		r1c1_add_row( rBuf, rRef.Ref1 );
+		r1c1_add_col( rBuf, rRef.Ref1 );
+		if (!bSingleRef)
+		{
+			rBuf.append (sal_Unicode ( ':' ) );
+			r1c1_add_row( rBuf, rRef.Ref2 );
+			r1c1_add_col( rBuf, rRef.Ref2 );
+		}
+	}
+
+	ParseResult parseAnyToken( const String& rFormula,
+							   xub_StrLen nSrcPos,
+							   const CharClass* pCharClass) const
+	{
+        static const sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
+            KParseTokens::ASC_UNDERSCORE ;
+        static const sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT |
+            KParseTokens::ASC_COLON;
+        // '?' allowed in range names because of Xcl :-/
+		static const String aAddAllowed = String::CreateFromAscii( "?-[]" );
+
+		return pCharClass->parseAnyToken( rFormula,
+                nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
+	}
+};
+
+static const ConventionXL_R1C1 ConvXL_R1C1;
+static const ScCompiler::Convention *pConvXL_R1C1 = &ConvXL_R1C1;
+
+//-----------------------------------------------------------------------------
+ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,
+                        const ScTokenArray& rArr )
+        :
+        aPos( rPos ),
+        pSymbolTable( pSymbolTableNative ),
+        pSymbolHashMap( pSymbolHashMapNative ),
+        pCharClass( ScGlobal::pCharClass ),
+        nRecursion(0),
+        bAutoCorrect( FALSE ),
+        bCorrected( FALSE ),
+        bCompileForFAP( FALSE ),
+        bIgnoreErrors( FALSE ),
+        bImportXML ( FALSE )
+{
+    if (!nAnzStrings)
+        Init();
+    pArr = (ScTokenArray*) &rArr;
+    pDoc = pDocument;
+
+	if (NULL != pDoc)
+		SetRefConvention( pDoc->GetAddressConvention() );
+	else
+		SetRefConvention( pConvOOO_A1 );
+
+    nMaxTab = pDoc->GetTableCount() - 1;
+    pStack = NULL;
+    nNumFmt = NUMBERFORMAT_UNDEFINED;
+}
+
+ScCompiler::ScCompiler(ScDocument* pDocument, const ScAddress& rPos )
+        :
+        aPos( rPos ),
+        pSymbolTable( pSymbolTableNative ),
+        pSymbolHashMap( pSymbolHashMapNative ),
+        pCharClass( ScGlobal::pCharClass ),
+        nRecursion(0),
+        bAutoCorrect( FALSE ),
+        bCorrected( FALSE ),
+        bCompileForFAP( FALSE ),
+        bIgnoreErrors( FALSE ),
+        bImportXML ( FALSE )
+{
+    if (!nAnzStrings)
+        Init();
+    pDoc = pDocument;
+
+	if (NULL != pDoc)
+		SetRefConvention( pDoc->GetAddressConvention() );
+	else
+		SetRefConvention( pConvOOO_A1 );
+
+    nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
+    pStack = NULL;
+    nNumFmt = NUMBERFORMAT_UNDEFINED;
+}
+
+void ScCompiler::CheckTabQuotes( String& rString,
+								 const ScAddress::Convention eConv )
+{
+    register const sal_Unicode* p = rString.GetBuffer();
+    register const sal_Unicode* const pEnd = p + rString.Len();
+	bool bNeedsQuote = false;
+
+    while ( p < pEnd )
+    {
+        if( !IsWordChar( *p ) )
+        {
+			bNeedsQuote = true;
+			break;
+        }
+        p++;
+    }
+    if ( CharClass::isAsciiNumeric( rString ) )
+    {
+			bNeedsQuote = true;
+    }
+
+	switch ( eConv ) {
+	default :
+	case ScAddress::CONV_UNSPECIFIED :
+	case ScAddress::CONV_OOO :
+		break;
+	case ScAddress::CONV_XL_A1 :
+	case ScAddress::CONV_XL_R1C1 :
+		if( bNeedsQuote )
+		{
+			static const String one_quote = static_cast<sal_Unicode>( '\'' );
+			static const String two_quote = String::CreateFromAscii( "''" );
+			// escape embedded quotes
+			rString.SearchAndReplaceAll( one_quote, two_quote );
+		}
+		break;
+	}
+
+	if( bNeedsQuote )
+	{
+		rString.Insert( '\'', 0 );
+		rString += '\'';
+	}
+}
 
 //---------------------------------------------------------------------------
 
+void ScCompiler::SetCompileXML( BOOL bVal )
+{
+	SetRefConvention( bVal ? pConvOOO_A1_XML : pConvOOO_A1 );
+}
+void ScCompiler::SetRefConvention( ScAddress::Convention eConv )
+{
+	switch ( eConv ) {
+	case ScAddress::CONV_UNSPECIFIED :
+		break;
+	default :
+	case ScAddress::CONV_OOO :		SetRefConvention( pConvOOO_A1 ); break;
+	case ScAddress::CONV_XL_A1 :	SetRefConvention( pConvXL_A1 );  break;
+	case ScAddress::CONV_XL_R1C1 :	SetRefConvention( pConvXL_R1C1 ); break;
+	}
+}
+
+void ScCompiler::SetRefConvention( const ScCompiler::Convention *pConvP )
+{
+	pConv = pConvP;
+}
+
 void ScCompiler::SetError(USHORT nError)
 {
     if( !pArr->GetError() )
@@ -755,14 +1273,7 @@ xub_StrLen ScCompiler::NextSymbol()
     }
     if ( bi18n )
     {
-        using namespace ::com::sun::star::i18n;
         nSrcPos += nSpaces;
-        sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER |
-            KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR;
-        sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT |
-            KParseTokens::ASC_COLON;
-        // '?' allowed in range names because of Xcl :-/
-        static const String aAddAllowed( '?' );
         String aSymbol;
         USHORT nErr = 0;
         do
@@ -772,8 +1283,7 @@ xub_StrLen ScCompiler::NextSymbol()
             if ( pStart[nSrcPos] == '$' && pStart[nSrcPos+1] == '\'' )
                 aSymbol += pStart[nSrcPos++];
 
-            ParseResult aRes = pCharClass->parseAnyToken( aFormula,
-                nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed );
+            ParseResult aRes = pConv->parseAnyToken( aFormula, nSrcPos, pCharClass );
 
             if ( !aRes.TokenType )
                 SetError( nErr = errIllegalChar );      // parsed chars as string
@@ -980,7 +1490,8 @@ BOOL ScCompiler::IsReference( const Stri
         }
     }
     ScRange aRange( aPos, aPos );
-    USHORT nFlags = aRange.Parse( rName, pDoc );
+	const ScAddress::Details aDetails( pConv->meConv, aPos );
+    USHORT nFlags = aRange.Parse( rName, pDoc, aDetails );
     if( nFlags & SCA_VALID )
     {
         ScRawToken aToken;
@@ -1005,7 +1516,7 @@ BOOL ScCompiler::IsReference( const Stri
     else
     {
         ScAddress aAddr( aPos );
-        nFlags = aAddr.Parse( rName, pDoc );
+        nFlags = aAddr.Parse( rName, pDoc, aDetails );
         // 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 ) )
@@ -1112,7 +1623,7 @@ BOOL ScCompiler::IsColRowName( const Str
     BOOL bFound = FALSE;
     SingleRefData aRef;
     String aName( rName );
-    DeQuote( aName );
+    DeQuote( aName, pConv->meConv );
     SCTAB nThisTab = aPos.Tab();
     for ( short jThisTab = 1; jThisTab >= 0 && !bInList; jThisTab-- )
     {   // #50300# first check ranges on this sheet, in case of duplicated names
@@ -1185,7 +1696,7 @@ BOOL ScCompiler::IsColRowName( const Str
     }
     if ( !bInList && pDoc->GetDocOptions().IsLookUpColRowNames() )
     {   // search in current sheet
-        long nDistance, nMax;
+        long nDistance = 0, nMax = 0;
         long nMyCol = (long) aPos.Col();
         long nMyRow = (long) aPos.Row();
         BOOL bTwo = FALSE;
@@ -1452,12 +1963,12 @@ void ScCompiler::AutoCorrectParsedSymbol
         {
             String aSymbol( aCorrectedSymbol );
             String aDoc;
-            xub_StrLen nPos;
+            xub_StrLen nPosition;
             if ( aSymbol.GetChar(0) == '\''
-              && ((nPos = aSymbol.SearchAscii( "'#" )) != STRING_NOTFOUND) )
+              && ((nPosition = aSymbol.SearchAscii( "'#" )) != STRING_NOTFOUND) )
             {   // Split off 'Doc'#, may be d:\... or whatever
-                aDoc = aSymbol.Copy( 0, nPos + 2 );
-                aSymbol.Erase( 0, nPos + 2 );
+                aDoc = aSymbol.Copy( 0, nPosition + 2 );
+                aSymbol.Erase( 0, nPosition + 2 );
             }
             xub_StrLen nRefs = aSymbol.GetTokenCount( ':' );
             BOOL bColons;
@@ -1527,6 +2038,7 @@ void ScCompiler::AutoCorrectParsedSymbol
             if ( nRefs && nRefs <= 2 )
             {   // reference twisted? 4A => A4 etc.
                 String aTab[2], aRef[2];
+				const ScAddress::Details aDetails( pConv->meConv, aPos );
                 if ( nRefs == 2 )
                 {
                     aRef[0] = aSymbol.GetToken( 0, ':' );
@@ -1560,7 +2072,7 @@ void ScCompiler::AutoCorrectParsedSymbol
                     {
                         bChanged = TRUE;
                         ScAddress aAdr;
-                        bOk &= ((aAdr.Parse( aRef[j], pDoc ) & nMask) == nMask);
+                        bOk &= ((aAdr.Parse( aRef[j], pDoc, aDetails ) & nMask) == nMask);
                     }
                 }
                 if ( bChanged && bOk )
@@ -1661,11 +2173,15 @@ BOOL ScCompiler::NextNewToken()
         return FALSE;
 }
 
-ScTokenArray* ScCompiler::CompileString( const String& rFormula )
+ScTokenArray* ScCompiler::CompileString( const String& rFormula,
+										 ScAddress::Convention eConv )
 {
     ScTokenArray aArr;
     pArr = &aArr;
     aFormula = rFormula;
+
+	SetRefConvention( eConv );
+
     aFormula.EraseLeadingChars();
     aFormula.EraseTrailingChars();
     nSrcPos = 0;
@@ -1856,8 +2372,8 @@ BOOL ScCompiler::GetToken()
                 // in short: if it isn't a self-contained expression.
                 ScToken* p1 = pArr->PeekPrevNoSpaces();
                 ScToken* p2 = pArr->PeekNextNoSpaces();
-                OpCode eOp1 = (p1 ? p1->GetOpCode() : ocSep);
-                OpCode eOp2 = (p2 ? p2->GetOpCode() : ocSep);
+                OpCode eOp1 = (p1 ? p1->GetOpCode() : static_cast<OpCode>( ocSep ) );
+                OpCode eOp2 = (p2 ? p2->GetOpCode() : static_cast<OpCode>( ocSep ) );
                 BOOL bBorder1 = (eOp1 == ocSep || eOp1 == ocOpen);
                 BOOL bBorder2 = (eOp2 == ocSep || eOp2 == ocClose);
                 BOOL bAddPair = !(bBorder1 && bBorder2);
@@ -2021,8 +2537,8 @@ BOOL ScCompiler::GetToken()
                 ScToken* p1 = pArr->PeekPrevNoSpaces();
                 ScToken* p2 = pArr->PeekNextNoSpaces();
                 // begin/end of a formula => single
-                OpCode eOp1 = p1 ? p1->GetOpCode() : ocAdd;
-                OpCode eOp2 = p2 ? p2->GetOpCode() : ocAdd;
+                OpCode eOp1 = p1 ? p1->GetOpCode() : static_cast<OpCode>( ocAdd );
+                OpCode eOp2 = p2 ? p2->GetOpCode() : static_cast<OpCode>( ocAdd );
                 if ( eOp1 != ocColRowName && eOp1 != ocIntersect
                     && eOp2 != ocColRowName && eOp2 != ocIntersect )
                 {
@@ -2383,9 +2899,11 @@ void ScCompiler::Factor()
             case ocFormula:
             case ocInfo:
             // more than one parameters:
-                // ocIndirect otherwise would have to do StopListening and
-                // StartListening on a reference for every interpreted value.
+				// ocIndirect/ocIndirectXL otherwise would have to do
+				// StopListening and StartListening on a reference for every
+				// interpreted value.
             case ocIndirect:
+            case ocIndirectXL:
                 // ocOffset results in indirect references.
             case ocOffset:
                 pArr->SetRecalcModeAlways();
@@ -3741,21 +4259,21 @@ const String& ScCompiler::GetStringFromO
     return EMPTY_STRING;
 }
 
-ScToken* ScCompiler::CreateStringFromToken( String& rFormula, ScToken* pToken,
+ScToken* ScCompiler::CreateStringFromToken( String& rFormula, ScToken* pTokenP,
         BOOL bAllowArrAdvance )
 {
     rtl::OUStringBuffer aBuffer;
-    ScToken* p = CreateStringFromToken( aBuffer, pToken, bAllowArrAdvance );
+    ScToken* p = CreateStringFromToken( aBuffer, pTokenP, bAllowArrAdvance );
     rFormula += aBuffer;
     return p;
 }
 
-ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToken* pToken,
+ScToken* ScCompiler::CreateStringFromToken( rtl::OUStringBuffer& rBuffer, ScToken* pTokenP,
         BOOL bAllowArrAdvance )
 {
     BOOL bNext = TRUE;
     BOOL bSpaces = FALSE;
-    ScToken* t = pToken;
+    ScToken* t = pTokenP;
     OpCode eOp = t->GetOpCode();
     if( eOp >= ocAnd && eOp <= ocOr )
     {
@@ -3848,21 +4366,21 @@ ScToken* ScCompiler::CreateStringFromTok
                 {
                     String aStr;
                     pDoc->GetString( rRef.nCol, rRef.nRow, rRef.nTab, aStr );
-                    EnQuote( aStr );
+                    EnQuote( aStr, pConv->meConv );
                     rBuffer.append(aStr);
                 }
                 else
                 {
                     rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
-                    MakeRefStr( rBuffer, aRef, TRUE );
+					pConv->MakeRefStr (rBuffer, *this, aRef, TRUE );
                 }
             }
             else
-                MakeRefStr( rBuffer, aRef, TRUE );
+				pConv->MakeRefStr( rBuffer, *this, aRef, TRUE );
         }
             break;
         case svDoubleRef:
-            MakeRefStr( rBuffer, t->GetDoubleRef(), FALSE );
+			pConv->MakeRefStr( rBuffer, *this, t->GetDoubleRef(), FALSE );
             break;
         case svIndex:
         {
@@ -3877,7 +4395,7 @@ ScToken* ScCompiler::CreateStringFromTok
                         if (pData->HasType(RT_SHARED))
                             pData->UpdateSymbol( aBuffer, aPos,
                                         pSymbolTable == pSymbolTableEnglish,
-                                        bCompileXML );
+                                        pConv == pConvOOO_A1_XML );
                         else
                             aBuffer.append(pData->GetName());
                     }
@@ -3924,7 +4442,7 @@ ScToken* ScCompiler::CreateStringFromTok
             t = pArr->Next();
         return t;
     }
-    return pToken;
+    return pTokenP;
 }
 
 void ScCompiler::CreateStringFromTokenArray( String& rFormula )
@@ -3950,12 +4468,16 @@ void ScCompiler::CreateStringFromTokenAr
         t = CreateStringFromToken( rBuffer, t, TRUE );
 }
 
-BOOL ScCompiler::EnQuote( String& rStr )
+// Put quotes around string if non-alphanumeric characters are contained,
+// quote characters contained within are escaped by '\\'.
+BOOL ScCompiler::EnQuote( String& rStr,
+						  const ScAddress::Convention eConv )
 {
     sal_Int32 nType = ScGlobal::pCharClass->getStringType( rStr, 0, rStr.Len() );
     if ( !CharClass::isNumericType( nType )
             && CharClass::isAlphaNumericType( nType ) )
         return FALSE;
+
     xub_StrLen nPos = 0;
     while ( (nPos = rStr.Search( '\'', nPos)) != STRING_NOTFOUND )
     {
@@ -3967,8 +4489,9 @@ BOOL ScCompiler::EnQuote( String& rStr )
     return TRUE;
 }
 
-
-BOOL ScCompiler::DeQuote( String& rStr )
+// Remove quotes, escaped quotes are unescaped.
+BOOL ScCompiler::DeQuote( String& rStr,
+						  const ScAddress::Convention eConv )
 {
     xub_StrLen nLen = rStr.Len();
     if ( nLen > 1 && rStr.GetChar(0) == '\'' && rStr.GetChar( nLen-1 ) == '\'' )
diff -r -u -p sc/source/core/tool/interpr1.cxx sc/source/core/tool/interpr1.cxx
--- sc/source/core/tool/interpr1.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/tool/interpr1.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -5366,27 +5366,38 @@ void ScInterpreter::ScDBVarP()
 }
 
 
-void ScInterpreter::ScIndirect()
+void ScInterpreter::ScIndirectXL()
 {
 	BYTE nParamCount = GetByte();
-/*
-	if (nParamCount == 2)
-	{
-		double fBool = GetDouble();
-		if (fBool == 0.0)							// nur TRUE erlaubt!!
+	ScAddress::Convention conv = ScAddress::CONV_XL_A1;
+
+	if (nParamCount == 2 && 0. == GetDouble())
+		conv = ScAddress::CONV_XL_R1C1;
+
+	if ( MustHaveParamCount( nParamCount, 1, 2 )  )
 		{
-			SetIllegalParameter();
-			return;
-		}
+		ScAddress::Details const details( conv, aPos );
+		SCTAB nTab = aPos.Tab();
+		String sRefStr( GetString() );
+		ScRefAddress aRefAd, aRefAd2;
+		if ( ConvertDoubleRef( pDok, sRefStr, nTab, aRefAd, aRefAd2, details ) )
+			PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
+				aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab() );
+		else if ( ConvertSingleRef ( pDok, sRefStr, nTab, aRefAd, details ) )
+			PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() );
 		else
-			nParamCount = 1;
+			SetIllegalArgument();
 	}
-*/
+}
+void ScInterpreter::ScIndirect()
+{
+	BYTE nParamCount = GetByte();
 	if ( MustHaveParamCount( nParamCount, 1 )  )
 	{
 		SCTAB nTab = aPos.Tab();
 		String sRefStr( GetString() );
 		ScRefAddress aRefAd, aRefAd2;
+		/* Always OOO format which does not require a position */
 		if ( ConvertDoubleRef( pDok, sRefStr, nTab, aRefAd, aRefAd2 ) )
 			PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
 				aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab() );
@@ -5442,6 +5453,76 @@ void ScInterpreter::ScAdress()
 	}
 }
 
+void ScInterpreter::ScAdressXL()
+{
+	String	sTabStr;
+
+	BYTE	nParamCount = GetByte();
+	if( !MustHaveParamCount( nParamCount, 2, 5 ) )
+		return;
+
+	if( nParamCount >= 5 )
+		sTabStr = GetString();
+
+	ScAddress::Convention eConv = ScAddress::CONV_XL_A1;	// default
+	if( nParamCount >= 4 && (USHORT) ::rtl::math::approxFloor(GetDouble()) == 0 )
+		eConv = ScAddress::CONV_XL_R1C1;
+
+	USHORT	nFlags = SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE;	// default
+	if( nParamCount >= 3 )
+	{
+		USHORT n = (USHORT) ::rtl::math::approxFloor(GetDouble());
+		switch ( n )
+		{
+		default :
+			SetNoValue();
+			return;
+
+		case 5:
+		case 1 : break;	// default
+		case 6:
+		case 2 : nFlags = SCA_ROW_ABSOLUTE; break;
+		case 7:
+		case 3 : nFlags = SCA_COL_ABSOLUTE; break;
+		case 8:
+		case 4 : nFlags = 0; break;	// both relative
+		}
+	}
+	nFlags |= SCA_VALID | SCA_VALID_ROW | SCA_VALID_COL;
+
+	SCCOL nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble());
+	SCROW nRow = (SCROW) ::rtl::math::approxFloor(GetDouble());
+	if( eConv == ScAddress::CONV_XL_R1C1 )
+	{
+		// YUCK!  The XL interface actually treats rel R1C1 refs differently
+		// than A1
+		if( !(nFlags & SCA_COL_ABSOLUTE) )
+			nCol += aPos.Col() + 1;
+		if( !(nFlags & SCA_ROW_ABSOLUTE) )
+			nRow += aPos.Row() + 1;
+	}
+
+	if( nCol < 1 || nCol > MAXCOL + 1 || nRow < 1 || nRow > MAXROW + 1 )
+	{
+		SetNoValue();
+		return;
+	}
+
+	String aRefStr;
+	const ScAddress::Details	aDetails( eConv, aPos );
+	const ScAddress aAdr( nCol-1, nRow-1, 0);
+	aAdr.Format( aRefStr, nFlags, pDok, aDetails );
+
+	if( nParamCount >= 5 )
+	{	// TODO Do we need to quote this ?
+		sTabStr += static_cast<sal_Unicode>('!');
+		sTabStr += aRefStr;
+		PushString( sTabStr );
+	}
+	else
+		PushString( aRefStr );
+}
+
 
 void ScInterpreter::ScOffset()
 {
diff -r -u -p sc/source/core/tool/interpr4.cxx sc/source/core/tool/interpr4.cxx
--- sc/source/core/tool/interpr4.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/tool/interpr4.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -3401,7 +3401,9 @@ StackVar ScInterpreter::Interpret()
                 case ocDBVar            : ScDBVar();                    break;
                 case ocDBVarP           : ScDBVarP();                   break;
                 case ocIndirect         : ScIndirect();                 break;
+                case ocIndirectXL       : ScIndirectXL();               break;
                 case ocAdress           : ScAdress();                   break;
+                case ocAdressXL         : ScAdressXL();                 break;
                 case ocMatch            : ScMatch();                    break;
                 case ocCountEmptyCells  : ScCountEmptyCells();          break;
                 case ocCountIf          : ScCountIf();                  break;
diff -r -u -p sc/source/core/tool/rangelst.cxx sc/source/core/tool/rangelst.cxx
--- sc/source/core/tool/rangelst.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/tool/rangelst.cxx	2006-09-05 23:04:35.000000000 -0400
@@ -66,10 +66,33 @@ void ScRangeList::RemoveAll()
 	Clear();
 }
 
-USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask )
+static void defaultDelimiter( char& cDelimiter, ScAddress::Convention eConv)
+{
+	if( cDelimiter == 0)
+	{
+		switch( eConv )
+		{
+		default :
+		case ScAddress::CONV_OOO :
+			cDelimiter = ';';
+			break;
+
+		case ScAddress::CONV_XL_A1 :
+		case ScAddress::CONV_XL_R1C1 :
+			cDelimiter = ',';
+			break;
+		}
+	}
+}
+
+USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask,
+						   ScAddress::Convention eConv,
+						   char cDelimiter )
 {
 	if ( rStr.Len() )
 	{
+		defaultDelimiter( cDelimiter, eConv);
+
 		nMask |= SCA_VALID;				// falls das jemand vergessen sollte
 		USHORT nResult = (USHORT)~0;	// alle Bits setzen
 		ScRange	aRange;
@@ -82,10 +105,11 @@ USHORT ScRangeList::Parse( const String&
 		}
 		else
 			nTab = 0;
-		USHORT nTCount = rStr.GetTokenCount();
+		USHORT nTCount = rStr.GetTokenCount( cDelimiter );
 		for ( USHORT i=0; i<nTCount; i++ )
 		{
-			aOne = rStr.GetToken(i);
+			aOne = rStr.GetToken( i, cDelimiter );
+			// FIXME : broken for Lotus
 			if ( aOne.Search( ':' ) == STRING_NOTFOUND )
 			{	// Range muss es sein
 				String aStrTmp( aOne );
@@ -93,7 +117,7 @@ USHORT ScRangeList::Parse( const String&
 				aOne += aStrTmp;
 			}
 			aRange.aStart.SetTab( nTab );	// Default Tab wenn nicht angegeben
-			USHORT nRes = aRange.Parse( aOne, pDoc );
+			USHORT nRes = aRange.Parse( aOne, pDoc, eConv );
 			if ( (nRes & nMask) == nMask )
 				Append( aRange );
 			nResult &= nRes;		// alle gemeinsamen Bits bleiben erhalten
@@ -105,16 +129,21 @@ USHORT ScRangeList::Parse( const String&
 }
 
 
-void ScRangeList::Format( String& rStr, USHORT nFlags, ScDocument* pDoc ) const
+void ScRangeList::Format( String& rStr, USHORT nFlags, ScDocument* pDoc,
+						  ScAddress::Convention eConv,
+						  char cDelimiter ) const
 {
 	rStr.Erase();
+
+	defaultDelimiter( cDelimiter, eConv);
+
 	ULONG nCnt = Count();
 	for ( ULONG nIdx = 0; nIdx < nCnt; nIdx++ )
 	{
 		String aStr;
-		GetObject( nIdx )->Format( aStr, nFlags, pDoc );
+		GetObject( nIdx )->Format( aStr, nFlags, pDoc, eConv );
 		if ( nIdx )
-			rStr += ';';
+			rStr += cDelimiter;
 		rStr += aStr;
 	}
 }
@@ -789,6 +818,7 @@ ScRangePairList::QsortNameCompare( const
 			}
 			return 0;
 	}
+	return 0; // just in case
 }
 
 
diff -r -u -p sc/source/core/tool/rangenam.cxx sc/source/core/tool/rangenam.cxx
--- sc/source/core/tool/rangenam.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/tool/rangenam.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -535,7 +535,6 @@ void ScRangeData::UpdateTabRef(SCTAB nOl
 
 void ScRangeData::MakeValidName( String& rName )		// static
 {
-	if (!ScCompiler::HasCharTable())
 		ScCompiler::Init();
 
 	//	ungueltige Zeichen vorne weglassen
@@ -559,27 +558,24 @@ void ScRangeData::MakeValidName( String&
 	}
 
 	// Name darf keine Referenz beinhalten, wie in IsNameValid
-	BOOL bOk;
-	do
-	{
-		bOk = TRUE;
+	ScAddress aAddr;
 		ScRange aRange;
-		if( aRange.Parse( rName, NULL ) )
-			bOk = FALSE;
-		else
+	int nConv = ScAddress::CONV_UNSPECIFIED; // use int so that op++ works
+
+	// Ensure that the proposed name is not an address under any convention
+	while ( ++nConv != ScAddress::CONV_LAST )
 		{
-			ScAddress aAddr;
-			if ( aAddr.Parse( rName, NULL ) )
-				bOk = FALSE;
-		}
-		if ( !bOk )
-		{	//! Range Parse auch bei Bereich mit ungueltigem Tabellennamen gueltig
+		ScAddress::Details details( static_cast<ScAddress::Convention>( nConv ) );
+		while( aRange.Parse( rName, NULL, details )
+			   || aAddr.Parse( rName, NULL, details ) )
+		{
+			//! Range Parse auch bei Bereich mit ungueltigem Tabellennamen gueltig
 			//! Address Parse dito, Name erzeugt deswegen bei Compile ein #REF!
 			if ( rName.SearchAndReplace( ':', '_' ) == STRING_NOTFOUND
 			  && rName.SearchAndReplace( '.', '_' ) == STRING_NOTFOUND )
 				rName.Insert('_',0);
 		}
-	} while ( !bOk );
+	}
 }
 
 BOOL ScRangeData::IsNameValid( const String& rName, ScDocument* pDoc )
@@ -598,12 +594,12 @@ BOOL ScRangeData::IsNameValid( const Str
 	// Parse nicht auf VALID pruefen, es reicht, wenn irgendein Bestandteil
 	// erkannt wurde
 	ScRange aRange;
-	if( aRange.Parse( rName, pDoc ) )
+	if( aRange.Parse( rName, pDoc ) )	// THIS IS WRONG
 		return FALSE;
 	else
 	{
 		ScAddress aAddr;
-		if ( aAddr.Parse( rName, pDoc ) )
+		if ( aAddr.Parse( rName, pDoc ) )	// THIS IS WRONG
 			return FALSE;
 	}
 	return TRUE;
diff -r -u -p sc/source/core/tool/rangeutl.cxx sc/source/core/tool/rangeutl.cxx
--- sc/source/core/tool/rangeutl.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/tool/rangeutl.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -56,10 +56,14 @@
 BOOL ScRangeUtil::MakeArea( const String&	rAreaStr,
 							ScArea&			rArea,
 							ScDocument*		pDoc,
-							SCTAB			nTab ) const
+							SCTAB			nTab,
+							ScAddress::Details const & rDetails ) const
 {
 	// Eingabe in rAreaStr: "$Tabelle1.$A1:$D17"
 
+	// BROKEN BROKEN BROKEN
+	// but it is only used in the consolidate dialog.  Ignore for now.
+
 	BOOL		nSuccess	= FALSE;
 	USHORT		nPointPos	= rAreaStr.Search('.');
 	USHORT		nColonPos	= rAreaStr.Search(':');
@@ -74,7 +78,7 @@ BOOL ScRangeUtil::MakeArea( const String
 			aStrArea += rAreaStr.Copy( nPointPos+1 ); // '.' nicht mitkopieren
 		}
 
-	nSuccess = ConvertDoubleRef( pDoc, aStrArea, nTab, startPos, endPos );
+	nSuccess = ConvertDoubleRef( pDoc, aStrArea, nTab, startPos, endPos, rDetails );
 
 	if ( nSuccess )
 		rArea = ScArea( startPos.Tab(),
@@ -90,6 +94,9 @@ void ScRangeUtil::CutPosString( const St
 								String&			thePosStr ) const
 {
 	String	aPosStr;
+	// BROKEN BROKEN BROKEN
+	// but it is only used in the consolidate dialog.  Ignore for now.
+
 	USHORT	nColonPos = theAreaStr.Search(':');
 
 	if ( nColonPos != STRING_NOTFOUND )
@@ -106,12 +113,16 @@ BOOL ScRangeUtil::IsAbsTabArea( const St
 								ScDocument*		pDoc,
 								ScArea***		pppAreas,
 								USHORT*			pAreaCount,
-								BOOL			bAcceptCellRef ) const
+								BOOL			bAcceptCellRef,
+								ScAddress::Details const & rDetails ) const
 {
 	DBG_ASSERT( pDoc, "Kein Dokument uebergeben!" );
 	if ( !pDoc )
 		return FALSE;
 
+	// BROKEN BROKEN BROKEN
+	// but it is only used in the consolidate dialog.  Ignore for now.
+
 	/*
 	 * Erwartet wird ein String der Form
 	 *		"$Tabelle1.$A$1:$Tabelle3.$D$17"
@@ -146,9 +157,9 @@ BOOL ScRangeUtil::IsAbsTabArea( const St
 		aStartPosStr = aTempAreaStr.Copy( 0,		   nColonPos  );
 		aEndPosStr	 = aTempAreaStr.Copy( nColonPos+1, STRING_LEN );
 
-		if ( ConvertSingleRef( pDoc, aStartPosStr, 0, aStartPos ) )
+		if ( ConvertSingleRef( pDoc, aStartPosStr, 0, aStartPos, rDetails ) )
 		{
-			if ( ConvertSingleRef( pDoc, aEndPosStr, aStartPos.Tab(), aEndPos ) )
+			if ( ConvertSingleRef( pDoc, aEndPosStr, aStartPos.Tab(), aEndPos, rDetails ) )
 			{
 				aStartPos.SetRelCol( FALSE );
 				aStartPos.SetRelRow( FALSE );
@@ -194,13 +205,14 @@ BOOL ScRangeUtil::IsAbsArea( const Strin
 							 SCTAB			nTab,
 							 String*		pCompleteStr,
 							 ScRefAddress*	pStartPos,
-							 ScRefAddress*	pEndPos ) const
+							 ScRefAddress*	pEndPos,
+							 ScAddress::Details const & rDetails ) const
 {
 	BOOL		bIsAbsArea = FALSE;
 	ScRefAddress	startPos;
 	ScRefAddress	endPos;
 
-	bIsAbsArea = ConvertDoubleRef( pDoc, rAreaStr, nTab, startPos, endPos );
+	bIsAbsArea = ConvertDoubleRef( pDoc, rAreaStr, nTab, startPos, endPos, rDetails );
 
 	if ( bIsAbsArea )
 	{
@@ -213,9 +225,9 @@ BOOL ScRangeUtil::IsAbsArea( const Strin
 
 		if ( pCompleteStr )
 		{
-			*pCompleteStr  = startPos.GetRefString( pDoc, MAXTAB+1 );
+			*pCompleteStr  = startPos.GetRefString( pDoc, MAXTAB+1, rDetails );
 			*pCompleteStr += ':';
-			*pCompleteStr += endPos  .GetRefString( pDoc, nTab );
+			*pCompleteStr += endPos  .GetRefString( pDoc, nTab, rDetails );
 		}
 
 		if ( pStartPos && pEndPos )
@@ -234,13 +246,13 @@ BOOL ScRangeUtil::IsAbsPos( const String
 							ScDocument*		pDoc,
 							SCTAB			nTab,
 							String*			pCompleteStr,
-							ScRefAddress*	pPosTripel ) const
+							ScRefAddress*	pPosTripel,
+							ScAddress::Details const & rDetails ) const
 {
 	BOOL		bIsAbsPos = FALSE;
 	ScRefAddress	thePos;
 
-	bIsAbsPos = ConvertSingleRef( pDoc, rPosStr, nTab, thePos );
-
+	bIsAbsPos = ConvertSingleRef( pDoc, rPosStr, nTab, thePos, rDetails ); 
 	thePos.SetRelCol( FALSE );
 	thePos.SetRelRow( FALSE );
 	thePos.SetRelTab( FALSE );
@@ -250,7 +262,7 @@ BOOL ScRangeUtil::IsAbsPos( const String
 		if ( pPosTripel )
 			*pPosTripel = thePos;
 		if ( pCompleteStr )
-			*pCompleteStr = thePos.GetRefString( pDoc, MAXTAB+1 );
+			*pCompleteStr = thePos.GetRefString( pDoc, MAXTAB+1, rDetails );
 	}
 
 	return bIsAbsPos;
@@ -263,8 +275,8 @@ BOOL ScRangeUtil::MakeRangeFromName	(
 	ScDocument*		pDoc,
 	SCTAB			nCurTab,
 	ScRange&		rRange,
-	RutlNameScope 	eScope
-								  ) const
+	RutlNameScope 	eScope,
+	ScAddress::Details const & rDetails ) const
 {
 	BOOL bResult=FALSE;
 	ScRangeUtil		aRangeUtil;
@@ -289,7 +301,7 @@ BOOL ScRangeUtil::MakeRangeFromName	(
 			pData->GetSymbol( aStrArea );
 
 			if ( IsAbsArea( aStrArea, pDoc, nCurTab,
-									   NULL, &aStartPos, &aEndPos ) )
+							NULL, &aStartPos, &aEndPos, rDetails ) )
 			{
 				nTab	   = aStartPos.Tab();
 				nColStart  = aStartPos.Col();
@@ -303,7 +315,7 @@ BOOL ScRangeUtil::MakeRangeFromName	(
 				CutPosString( aStrArea, aStrArea );
 
 				if ( IsAbsPos( aStrArea, pDoc, nCurTab,
-										  NULL, &aStartPos ) )
+										  NULL, &aStartPos, rDetails ) )
 				{
 					nTab	   = aStartPos.Tab();
 					nColStart  = nColEnd = aStartPos.Col();
@@ -424,13 +436,14 @@ SvStream& operator<< ( SvStream& rStream
 
 //------------------------------------------------------------------------
 
-void ScArea::GetString( String& rStr, BOOL bAbsolute, ScDocument* pDoc ) const
+void ScArea::GetString( String& rStr, BOOL bAbsolute, ScDocument* pDoc,
+						ScAddress::Details const & rDetails ) const
 {
 	ScRange aRange( ScAddress( nColStart, nRowStart, nTab ),
 					ScAddress( nColEnd,   nRowEnd,   nTab ) );
 	USHORT  nFlags = bAbsolute ? SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE : 0;
 
-	aRange.Format( rStr, nFlags, pDoc );
+	aRange.Format( rStr, nFlags, pDoc, rDetails );
 }
 
 //------------------------------------------------------------------------
diff -r -u -p sc/source/core/tool/reffind.cxx sc/source/core/tool/reffind.cxx
--- sc/source/core/tool/reffind.cxx	2006-09-05 23:35:39.000000000 -0400
+++ sc/source/core/tool/reffind.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -73,9 +73,11 @@ inline BOOL IsText( BOOL& bQuote, sal_Un
 	return IsText( c );
 }
 
-ScRefFinder::ScRefFinder(const String& rFormula, ScDocument* pDocument) :
+ScRefFinder::ScRefFinder(const String& rFormula, ScDocument* pDocument,
+			 ScAddress::Convention eConvP) :
 	aFormula( rFormula ),
-	pDoc( pDocument )
+	pDoc( pDocument ),
+	eConv( eConvP )
 {
 	nSelStart = nSelEnd = nFound = 0;
 }
diff -r -u -p sc/source/filter/excel/excdoc.cxx sc/source/filter/excel/excdoc.cxx
--- sc/source/filter/excel/excdoc.cxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/excel/excdoc.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -326,7 +326,7 @@ void ExcTable::FillAsTable( size_t nCode
     {
         Add( new ExcBof8 );
         Add( new XclCalccount( rDoc ) );
-        Add( new XclRefmode() );
+        Add( new XclRefmode( rDoc ) );
         Add( new XclIteration( rDoc ) );
         Add( new XclDelta( rDoc ) );
         Add( new ExcDummy8_02 );
diff -r -u -p sc/source/filter/excel/excform.cxx sc/source/filter/excel/excform.cxx
--- sc/source/filter/excel/excform.cxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/source/filter/excel/excform.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -1372,12 +1372,6 @@ void ExcelToSc::DoMulArgs( DefTokenId eI
 		if( eId == ocPercentrank && nAnz == 3 )
 			nSkipEnd = 0;		// letzten Parameter bei Bedarf weglassen
 
-		else if( eId == ocIndirect && nAnz == 2 )
-			nSkipEnd = 0;
-
-		else if( eId == ocAdress && nAnz > 3 )
-			nNull = nAnz - 4;
-
 		// Joost-Spezialfaelle
 		else if( eId == ocIf )
 		{
diff -r -u -p sc/source/filter/excel/excimp8.cxx sc/source/filter/excel/excimp8.cxx
--- sc/source/filter/excel/excimp8.cxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/excel/excimp8.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -190,6 +190,12 @@ void ImportExcel8::Iteration( void )
 }
 
 
+void ImportExcel8::RefMode( void )
+{
+	pD->SetAddressConvention( (aIn.ReaduInt16() == 0)
+				  ? ScAddress::CONV_XL_R1C1
+				  : ScAddress::CONV_OOO );
+}
 void ImportExcel8:: WinProtection( void )
 {
     if( aIn.ReaduInt16() != 0 )
diff -r -u -p sc/source/filter/excel/impop.cxx sc/source/filter/excel/impop.cxx
--- sc/source/filter/excel/impop.cxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/excel/impop.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -554,8 +554,8 @@ void ImportExcel::Array25( void )
         aMarkData.SelectOneTable( GetCurrScTab() );
         pD->InsertMatrixFormula( static_cast<SCCOL>(nFirstCol),
                 static_cast<SCROW>(nFirstRow), static_cast<SCCOL>(nLastCol),
-                static_cast<SCROW>(nLastRow), aMarkData, EMPTY_STRING,
-                pErgebnis );
+                static_cast<SCROW>(nLastRow), aMarkData,
+				EMPTY_STRING, pErgebnis );
 	}
 }
 
@@ -1014,8 +1014,8 @@ void ImportExcel::Array34( void )
         aMarkData.SelectOneTable( GetCurrScTab() );
         pD->InsertMatrixFormula( static_cast<SCCOL>(nFirstCol),
                 static_cast<SCROW>(nFirstRow), static_cast<SCCOL>(nLastCol),
-                static_cast<SCROW>(nLastRow), aMarkData, EMPTY_STRING,
-                pErgebnis);
+                static_cast<SCROW>(nLastRow), aMarkData,
+				EMPTY_STRING, pErgebnis);
 	}
 }
 
diff -r -u -p sc/source/filter/excel/read.cxx sc/source/filter/excel/read.cxx
--- sc/source/filter/excel/read.cxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/excel/read.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -1145,6 +1145,7 @@ FltError ImportExcel8::Read( void )
                     case 0x0206:
                     case 0x0406:    Formula25();            break;  // FORMULA      [ 2  5   ]
                     case 0x000C:    Calccount();            break;  // CALCCOUNT
+					case 0x000F:    RefMode();				break;	// REFMODE
                     case 0x0010:    Delta();                break;  // DELTA
                     case 0x0011:    Iteration();            break;  // ITERATION
                     case 0x001C:    Note();                 break;  // NOTE         [ 2345   ]
diff -r -u -p sc/source/filter/excel/xlformula.cxx sc/source/filter/excel/xlformula.cxx
--- sc/source/filter/excel/xlformula.cxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/source/filter/excel/xlformula.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -187,7 +187,8 @@ static const XclFunctionInfo saFuncTable
     { ocLIA,                142,    3,  3,  V, { V } },
     { ocDIA,                143,    4,  4,  V, { V } },
     { ocGDA,                144,    4,  5,  V, { V } },
-    { ocIndirect,           148,    1,  2,  R, { V }, EXC_FUNCFLAG_VOLATILE },
+    { ocIndirectXL,         148,    1,  2,  R, { V }, EXC_FUNCFLAG_VOLATILE },
+    { ocIndirect,           148,    1,  2,  R, { V }, EXC_FUNCFLAG_VOLATILE | EXC_FUNCFLAG_EXPORTONLY },
     { ocClean,              162,    1,  1,  V, { V } },
     { ocMatDet,             163,    1,  1,  V, { A } },
     { ocMatInv,             164,    1,  1,  A, { A } },
@@ -219,7 +220,8 @@ static const XclFunctionInfo saFuncTable
     { ocRKP,                51,     1,  4,  A, { R, R, V, V } },    // BIFF2: 1-2, BIFF3: 1-4
     { ocGrowth,             52,     1,  4,  A, { R, R, R, V } },    // BIFF2: 1-3, BIFF3: 1-4
     { ocTrunc,              197,    1,  2,  V, { V } },             // BIFF2: 1,   BIFF3: 1-2
-    { ocAdress,             219,    2,  5,  V, { V, V, V, E, V } },
+    { ocAdressXL,           219,    2,  5,  V, { V, V, V, V, V } },
+    { ocAdress,             219,    2,  5,  V, { V, V, V, E, V }, EXC_FUNCFLAG_EXPORTONLY },
     { ocGetDiffDate360,     220,    2,  2,  V, { V, V, C, I } },
     { ocGetActDate,         221,    0,  0,  V, {}, EXC_FUNCFLAG_VOLATILE },
     { ocVBD,                222,    5,  7,  V, { V } },
diff -r -u -p sc/source/filter/inc/excimp8.hxx sc/source/filter/inc/excimp8.hxx
--- sc/source/filter/inc/excimp8.hxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/inc/excimp8.hxx	2006-08-24 10:45:05.000000000 -0400
@@ -76,6 +76,7 @@ class ImportExcel8 : public ImportExcel
 
 		void					Calccount( void );				// 0x0C
         void                    Precision( void );              // 0x0E
+		void					RefMode( void );				// 0x0F
 		void					Delta( void );					// 0x10
 		void					Iteration( void );				// 0x11
 		void					Note( void );					// 0x1C
diff -r -u -p sc/source/filter/inc/xcl97dum.hxx sc/source/filter/inc/xcl97dum.hxx
--- sc/source/filter/inc/xcl97dum.hxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/inc/xcl97dum.hxx	2006-08-24 10:45:05.000000000 -0400
@@ -97,15 +97,4 @@ public:
 };
 
 
-class XclRefmode : public ExcDummyRec
-{
-private:
-    static const BYTE       pMyData[];
-    static const sal_Size   nMyLen;
-public:
-    virtual sal_Size        GetLen( void ) const;
-    virtual const BYTE*     GetData( void ) const;
-};
-
-
 #endif // _XCL97DUM_HXX
diff -r -u -p sc/source/filter/inc/xcl97rec.hxx sc/source/filter/inc/xcl97rec.hxx
--- sc/source/filter/inc/xcl97rec.hxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/inc/xcl97rec.hxx	2006-08-24 10:45:05.000000000 -0400
@@ -506,6 +506,20 @@ public:
 	virtual	const BYTE*			GetData( void ) const;
 };
 
+class XclRefmode : public ExcRecord
+{
+private:
+	UINT16					    eConv;
+protected:
+	virtual void				SaveCont( XclExpStream& rStrm );
+public:
+								XclRefmode( ScDocument& rDoc );
+
+	virtual	UINT16				GetNum() const;
+	virtual	ULONG				GetLen() const;
+};
+
+
 
 // -------------------------------------------------------------------
 
diff -r -u -p sc/source/filter/lotus/lotform.cxx sc/source/filter/lotus/lotform.cxx
--- sc/source/filter/lotus/lotform.cxx	2006-09-05 23:35:38.000000000 -0400
+++ sc/source/filter/lotus/lotform.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -1056,7 +1056,7 @@ DefTokenId LotusToSc::IndexToToken( BYTE
 		ocTrue,				//  112 W()
 		ocExact,			//  113 Exact()
 		ocNoName,			//  114 Call()
-		ocIndirect,			//  115 @@()
+		ocIndirectXL,		//  115 @@()
 		ocZins,				//  116 Rate()
 		ocNoName,			//  117 Term()
 		ocNoName,			//  118 Cterm()
@@ -1587,7 +1587,7 @@ DefTokenId LotusToSc::IndexToTokenWK123(
 		ocNoName,			//  112 W()
 		ocExact,			//  113 Exact()
 		ocNoName,			//  114 Call()
-		ocIndirect,			//  115 @@()
+		ocIndirectXL,		//  115 @@()
 		ocZins,				//  116 Rate()
 		ocNoName,			//  117 Term()
 		ocNoName,			//  118 Cterm()
diff -r -u -p sc/source/filter/xcl97/xcl97dum.cxx sc/source/filter/xcl97/xcl97dum.cxx
--- sc/source/filter/xcl97/xcl97dum.cxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/xcl97/xcl97dum.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -104,10 +104,6 @@ const BYTE ExcDummy8_02::pMyData[] = {
 const sal_Size ExcDummy8_02::nMyLen = sizeof(ExcDummy8_02::pMyData);
 
 
-const BYTE	XclRefmode::pMyData[] = { 0x0f, 0x00, 0x02, 0x00, 0x01, 0x00 };	// REFMODE
-const sal_Size  XclRefmode::nMyLen = sizeof( XclRefmode::pMyData );
-
-
 // --- class ExcDummy8_xx --------------------------------------------
 
 sal_Size ExcDummy8_00a::GetLen() const
@@ -173,18 +169,3 @@ const BYTE* ExcDummy8_02::GetData() cons
 	return pMyData;
 }
 
-
-
-sal_Size XclRefmode::GetLen( void ) const
-{
-	return nMyLen;
-}
-
-
-const BYTE* XclRefmode::GetData( void ) const
-{
-	return pMyData;
-}
-
-
-
diff -r -u -p sc/source/filter/xcl97/xcl97rec.cxx sc/source/filter/xcl97/xcl97rec.cxx
--- sc/source/filter/xcl97/xcl97rec.cxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/xcl97/xcl97rec.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -1302,6 +1302,28 @@ const BYTE* XclProtection::GetData( void
 
 
 
+void XclRefmode::SaveCont( XclExpStream& rStrm )
+{
+	rStrm << eConv;
+}
+
+
+XclRefmode::XclRefmode( ScDocument& rDoc )
+{
+	eConv = (rDoc.GetAddressConvention() == ScAddress::CONV_XL_R1C1) ? 0 : 1;
+}
+
+
+UINT16 XclRefmode::GetNum() const
+{
+	return 0x000f;
+}
+
+
+ULONG XclRefmode::GetLen() const
+{
+	return 2;
+}
 
 
 
diff -r -u -p sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx
--- sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/xml/XMLChangeTrackingImportHelper.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -111,7 +111,7 @@ ScBaseCell* ScMyCellInfo::CreateCell(ScD
 			ScAddress aPos;
 			sal_Int32 nOffset(0);
 			ScXMLConverter::GetAddressFromString(aPos, sFormulaAddress, pDoc, nOffset);
-			pCell = new ScFormulaCell(pDoc, aPos, sFormula, nMatrixFlag);
+			pCell = new ScFormulaCell(pDoc, aPos, sFormula, ScAddress::CONV_OOO, nMatrixFlag);
 			static_cast<ScFormulaCell*>(pCell)->SetMatColsRows(static_cast<SCCOL>(nMatrixCols), static_cast<SCROW>(nMatrixRows));
 		}
 
@@ -779,11 +779,11 @@ void ScXMLChangeTrackingImportHelper::Se
 						{
 							sal_uInt8 nMatrixFlag = static_cast<ScFormulaCell*>(pCell)->GetMatrixFlag();
 							String sFormula;
-							static_cast<ScFormulaCell*>(pCell)->GetFormula(sFormula);
+							static_cast<ScFormulaCell*>(pCell)->GetFormula(sFormula, ScAddress::CONV_OOO);
 							rtl::OUString sOUFormula(sFormula);
 							rtl::OUString sOUFormula2(sOUFormula.copy(2, sOUFormula.getLength() - 3));
 							String sFormula2(sOUFormula2);
-							pNewCell = new ScFormulaCell(pDoc, aAddress, sFormula2, nMatrixFlag);
+							pNewCell = new ScFormulaCell(pDoc, aAddress, sFormula2, ScAddress::CONV_OOO, nMatrixFlag);
 							if (pNewCell)
 							{
 								if (nMatrixFlag == MM_FORMULA)
diff -r -u -p sc/source/filter/xml/XMLConverter.cxx sc/source/filter/xml/XMLConverter.cxx
--- sc/source/filter/xml/XMLConverter.cxx	2006-09-05 23:35:40.000000000 -0400
+++ sc/source/filter/xml/XMLConverter.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -361,8 +361,10 @@ void ScXMLConverter::GetStringFromRange(
 		ScAddress aEndAddress( rRange.aEnd );
 		String sStartAddress;
 		String sEndAddress;
-		aStartAddress.Format( sStartAddress, nFormatFlags, (ScDocument*) pDocument );
-		aEndAddress.Format( sEndAddress, nFormatFlags, (ScDocument*) pDocument );
+		aStartAddress.Format( sStartAddress, nFormatFlags, (ScDocument*) pDocument,
+							  ScAddress::CONV_OOO );
+		aEndAddress.Format( sEndAddress, nFormatFlags, (ScDocument*) pDocument,
+							ScAddress::CONV_OOO );
 		OUString sOUStartAddress( sStartAddress );
 		sOUStartAddress += GetXMLToken( XML__COLON );
 		sOUStartAddress += OUString( sEndAddress );
diff -r -u -p sc/source/ui/Accessibility/AccessibleCellBase.cxx sc/source/ui/Accessibility/AccessibleCellBase.cxx
--- sc/source/ui/Accessibility/AccessibleCellBase.cxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/Accessibility/AccessibleCellBase.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -271,6 +271,7 @@ sal_Int32
 	String sName( ScResId(STR_ACC_CELL_NAME) );
 	String sAddress;
 	// Document not needed, because only the cell address, but not the tablename is needed
+	// always us OOO notation
 	maCellAddress.Format( sAddress, SCA_VALID, NULL );
 	sName.SearchAndReplaceAscii("%1", sAddress);
     return rtl::OUString(sName);
diff -r -u -p sc/source/ui/app/inputhdl.cxx sc/source/ui/app/inputhdl.cxx
--- sc/source/ui/app/inputhdl.cxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/app/inputhdl.cxx	2006-08-24 16:36:55.000000000 -0400
@@ -167,13 +167,27 @@ void ScInputHandler::InitRangeFinder( co
 
 		//	Text zwischen Trennern
 		nStart = nPos;
+handle_r1c1:
 		while ( nPos<nLen && !ScGlobal::UnicodeStrChr( aDelimiters.GetBuffer(), pChar[nPos] ) )
 			++nPos;
 
+		// for R1C1 '-' in R[-]... or C[-]... are not delimiters
+		// Nothing heroic here to ensure that there are '[]' around a negative
+		// integer.  we need to clean up this code.
+		if( nPos < nLen && nPos > 0 &&
+			'-' == pChar[nPos] && '[' == pChar[nPos-1] &&
+			NULL != pDoc &&
+			ScAddress::CONV_XL_R1C1 == pDoc->GetAddressConvention() )
+		{
+			nPos++;
+			goto handle_r1c1;
+		}
+
 		if ( nPos > nStart )
 		{
 			String aTest = rFormula.Copy( nStart, nPos-nStart );
-			USHORT nFlags = aRange.ParseAny( aTest, pDoc );
+			const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
+			USHORT nFlags = aRange.ParseAny( aTest, pDoc, aAddrDetails );
 			if ( nFlags & SCA_VALID )
 			{
 				//	Tabelle setzen, wenn nicht angegeben
@@ -245,7 +259,9 @@ void ScInputHandler::UpdateRange( USHORT
 		ScRange aJustified = rNew;
 		aJustified.Justify();			// Ref in der Formel immer richtigherum anzeigen
 		String aNewStr;
-		aJustified.Format( aNewStr, pData->nFlags, pDocView->GetViewData()->GetDocument() );
+		ScDocument* pDoc = pDocView->GetViewData()->GetDocument();
+		const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
+		aJustified.Format( aNewStr, pData->nFlags, pDoc, aAddrDetails );
 		ESelection aOldSel( 0, nOldStart, 0, nOldEnd );
 
 		DataChanging();
@@ -2443,6 +2459,7 @@ void ScInputHandler::SetReference( const
 	//	String aus Referenz erzeugen
 
 	String aRefStr;
+	const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
 	if (bOtherDoc)
 	{
 		//	Referenz auf anderes Dokument
@@ -2450,7 +2467,7 @@ void ScInputHandler::SetReference( const
 		DBG_ASSERT(rRef.aStart.Tab()==rRef.aEnd.Tab(), "nStartTab!=nEndTab");
 
 		String aTmp;
-		rRef.Format( aTmp, SCA_VALID|SCA_TAB_3D, pDoc );		// immer 3d
+		rRef.Format( aTmp, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails );		// immer 3d
 
 		SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
 		String aFileName = pObjSh->GetMedium()->GetName();
@@ -2464,9 +2481,9 @@ void ScInputHandler::SetReference( const
 	{
 		if ( ( rRef.aStart.Tab() != aCursorPos.Tab() ||
 				rRef.aStart.Tab() != rRef.aEnd.Tab() ) && pDoc )
-			rRef.Format( aRefStr, SCA_VALID|SCA_TAB_3D, pDoc );
+			rRef.Format( aRefStr, SCA_VALID|SCA_TAB_3D, pDoc, aAddrDetails );
 		else
-			rRef.Format( aRefStr, SCA_VALID );
+			rRef.Format( aRefStr, SCA_VALID, pDoc, aAddrDetails );
 	}
 
 	if (pTableView || pTopView)
@@ -2959,6 +2976,8 @@ void ScInputHandler::NotifyChange( const
 					const EditTextObject*	pData	= pState->GetEditData();
 					String					aString = pState->GetString();
 					BOOL					bTxtMod = FALSE;
+					ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell();
+					ScDocument* pDoc = pDocSh->GetDocument();
 
 					aCursorPos	= pState->GetPos();
 
@@ -2994,6 +3013,7 @@ void ScInputHandler::NotifyChange( const
 					if ( pInputWin )						// Bereichsanzeige
 					{
 						String aPosStr;
+						const ScAddress::Details aAddrDetails( pDoc, aCursorPos );
 
 						//	Ist der Bereich ein Name?
 						//!	per Timer suchen ???
@@ -3004,16 +3024,17 @@ void ScInputHandler::NotifyChange( const
 
 						if ( !aPosStr.Len() )			// kein Name -> formatieren
 						{
+							USHORT nFlags = 0;
+							if( aAddrDetails.eConv == ScAddress::CONV_XL_R1C1 )
+								nFlags |= SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE;
 							if ( rSPos != rEPos )
 							{
-								String aStr;
-								rSPos.Format( aPosStr, SCA_VALID );
-								aPosStr += ':';
-								rEPos.Format( aStr, SCA_VALID );
-								aPosStr += aStr;
+								ScRange r(rSPos, rEPos);
+								nFlags |= (nFlags << 4);
+								r.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
 							}
 							else
-								aCursorPos.Format( aPosStr, SCA_VALID );
+								aCursorPos.Format( aPosStr, SCA_VALID | nFlags, pDoc, aAddrDetails );
 						}
 
 						pInputWin->SetPosString(aPosStr);
diff -r -u -p sc/source/ui/attrdlg/condfrmt.cxx sc/source/ui/attrdlg/condfrmt.cxx
--- sc/source/ui/attrdlg/condfrmt.cxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/attrdlg/condfrmt.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -345,7 +345,7 @@ void ScConditionalFormatDlg::SetReferenc
 			RefInputStart(pEdActive);
 
 		String aStr;
-		rRef.Format( aStr, SCR_ABS_3D, pDoc );
+		rRef.Format( aStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention () );
 		String aVal( pEdActive->GetText() );
 		Selection aSel( pEdActive->GetSelection() );
         aSel.Justify();
diff -r -u -p sc/source/ui/docshell/docfunc.cxx sc/source/ui/docshell/docfunc.cxx
--- sc/source/ui/docshell/docfunc.cxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/docshell/docfunc.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -2226,6 +2226,42 @@ BOOL ScDocFunc::SetLayoutRTL( SCTAB nTab
 	return TRUE;
 }
 
+BOOL ScDocFunc::SetAddressConvention( ScAddress::Convention eConv )
+{
+	ScDocument* pDoc = rDocShell.GetDocument();
+
+	if ( pDoc->GetAddressConvention() == eConv )
+		return TRUE;
+
+	BOOL bUndo(pDoc->IsUndoEnabled());
+	ScDocShellModificator aModificator( rDocShell );
+
+	pDoc->SetAddressConvention( eConv );
+
+	if (bUndo)
+	{
+		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoSetAddressConvention( &rDocShell, eConv ) );
+	}
+
+	rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
+
+	ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+	if (NULL != pViewSh)
+	{
+	    pViewSh->UpdateInputHandler( FALSE, FALSE );
+	}
+
+	aModificator.SetDocumentModified();
+
+	SfxBindings* pBindings = rDocShell.GetViewBindings();
+	if (pBindings)
+	{
+		pBindings->Invalidate( FID_TAB_USE_R1C1 );
+	}
+
+	return TRUE;
+}
+
 BOOL ScDocFunc::RenameTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi )
 {
 	ScDocument* pDoc = rDocShell.GetDocument();
diff -r -u -p sc/source/ui/inc/colrowba.hxx sc/source/ui/inc/colrowba.hxx
--- sc/source/ui/inc/colrowba.hxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/inc/colrowba.hxx	2006-08-24 10:45:05.000000000 -0400
@@ -79,6 +79,8 @@ public:
 	virtual void		DrawInvert( long nDragPos );
 
 	virtual String		GetDragHelp( long nVal );
+
+			BOOL		UseNumericHeader() const;
 };
 
 
diff -r -u -p sc/source/ui/inc/docfunc.hxx sc/source/ui/inc/docfunc.hxx
--- sc/source/ui/inc/docfunc.hxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/inc/docfunc.hxx	2006-08-24 10:45:05.000000000 -0400
@@ -127,6 +127,8 @@ public:
 
 	BOOL			SetLayoutRTL( SCTAB nTab, BOOL bRTL, BOOL bApi );
 
+	BOOL	 	    SetAddressConvention( ScAddress::Convention eConv );
+
 	BOOL			SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges,
 									SCTAB nTab, ScSizeMode eMode, USHORT nSizeTwips,
 									BOOL bRecord, BOOL bApi );
diff -r -u -p sc/source/ui/inc/undoblk.hxx sc/source/ui/inc/undoblk.hxx
--- sc/source/ui/inc/undoblk.hxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/inc/undoblk.hxx	2006-08-24 10:45:05.000000000 -0400
@@ -720,6 +720,7 @@ public:
 private:
 	ScDocument*		pUndoDoc;
 	String			aFormula;
+	ScAddress::Convention eConv;
 	ULONG			nStartChangeAction;
 	ULONG			nEndChangeAction;
 
diff -r -u -p sc/source/ui/inc/undotab.hxx sc/source/ui/inc/undotab.hxx
--- sc/source/ui/inc/undotab.hxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/inc/undotab.hxx	2006-08-24 10:45:05.000000000 -0400
@@ -478,6 +478,26 @@ private:
 };
 
 
+class ScUndoSetAddressConvention : public ScSimpleUndo
+{
+public:
+					TYPEINFO();
+					ScUndoSetAddressConvention( ScDocShell* pShell,
+												ScAddress::Convention eConv );
+	virtual			~ScUndoSetAddressConvention();
+
+	virtual void	Undo();
+	virtual void	Redo();
+	virtual void	Repeat(SfxRepeatTarget& rTarget);
+	virtual BOOL	CanRepeat(SfxRepeatTarget& rTarget) const;
+
+	virtual String	GetComment() const;
+
+private:
+	ScAddress::Convention eNewConv, eOldConv;
+
+	void DoChange( ScAddress::Convention eConv );
+};
 
 #endif
 
diff -r -u -p sc/source/ui/src/globstr.src sc/source/ui/src/globstr.src
--- sc/source/ui/src/globstr.src	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/src/globstr.src	2006-08-24 10:45:05.000000000 -0400
@@ -1799,6 +1799,19 @@ Resource RID_GLOBSTR
 		Text [ de ] = "Tabelle wenden" ;
 		Text [ en-US ] = "Flip sheet" ;
 	};
+	String STR_UNDO_TAB_R1C1
+	{
+		Text [ en-US ] = "Toggle the use of R1C1 notation" ;
+		Text [ cs ] = "Přepni mezi R1C1 zápisem";
+		Text[ de ] = "Verwendung der R1C1-Notation umschalten";
+		Text[ es ] = "Alternar el uso de la notación R1C1";
+		Text[ fr ] = "Activer/Désactiver l'usage de la notation R1C1";
+		Text[ it ] = "Alterna l'utilizzo della notazione R1C1";
+		Text[ ja ] = "R1C1表記の使用をトグルする";
+		Text[ pt-BR ] = "Alterna o uso da notação R1C1";
+		Text[ zh-CN ] = "切换使用 R1C1 表示法";
+		Text[ zh-TW ] = "切換使用 R1C1 標記";
+	};
 	String STR_CHART_MAINTITLE
 	{
 		Text [ de ] = "Haupttitel" ;
diff -r -u -p sc/source/ui/src/scfuncs.src sc/source/ui/src/scfuncs.src
--- sc/source/ui/src/scfuncs.src	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/src/scfuncs.src	2006-08-24 10:45:05.000000000 -0400
@@ -9047,6 +9047,104 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
 			Text [ x-comment ] = " ";
 		};
 	};
+	Resource SC_OPCODE_ADRESS_XL
+	{
+		String 1 // Description
+		{
+			Text [ en-US ] = "Returns the reference to a cell as text." ;
+		Text[ cs ] = "Vrátí odkaz na buňku jako text.";
+		Text[ de ] = "Gibt die Referenz auf eine Zelle als Text zurück.";
+		Text[ es ] = "Devuelve la referencia a una celda en formato de texto.";
+		Text[ fr ] = "Retourne la référence à une cellule sous forme de texte.";
+		Text[ it ] = "Restituisce un riferimento a una cella come testo.";
+		Text[ ja ] = "セルへの参照をテキストとして戻します。";
+		Text[ pt-BR ] = "Retorna a referência a uma célula como texto.";
+		Text[ zh-CN ] = "将引用作为文本返回至单元。";
+		Text[ zh-TW ] = "以文字方式傳回儲存格參考。";
+			Text [ x-comment ] = " ";
+		};
+		ExtraData =
+		{
+			ID_FUNCTION_GRP_TABLE;
+			U2S( HID_FUNC_ADRESSE_XL );
+			5;	0;	0;	1;	1;	1;
+		};
+		String 2 // Name of Parameter 1
+		{
+			Text [ de ] = "Zeile" ;
+			Text [ en-US ] = "row" ;
+			Text [ cs ] = "Řádek";
+			Text [ x-comment ] = " ";
+		};
+		String 3 // Description of Parameter 1
+		{
+			Text [ de ] = "Die Zeilennummer der Zelle." ;
+			Text [ en-US ] = "The row number of the cell." ;
+			Text [ cs ] = "Číslo řádku buňky.";
+			Text [ x-comment ] = " ";
+		};
+		String 4 // Name of Parameter 2
+		{
+			Text [ de ] = "Spalte" ;
+			Text [ en-US ] = "column" ;
+			Text [ cs ] = "Sloupec";
+			Text [ x-comment ] = " ";
+		};
+		String 5 // Description of Parameter 2
+		{
+			Text [ de ] = "Die Spaltennummer der Zelle." ;
+			Text [ en-US ] = "The column number of the cell." ;
+			Text [ cs ] = "Číslo sloupce buňky.";
+			Text [ x-comment ] = " ";
+		};
+		String 6 // Name of Parameter 3
+		{
+			Text [ de ] = "ABS" ;
+			Text [ en-US ] = "ABS" ;
+			Text [ x-comment ] = " ";
+		};
+		String 7 // Description of Parameter 3
+		{
+			Text [ de ] = "Gibt an, ob absolute oder relative Referenzierung verwendet wird." ;
+			Text [ en-US ] = "Specifies whether absolute or relative referencing is to be used." ;
+			Text [ cs ] = "Specifikuje zda budou použity absolutní nebo relativní odkazy.";
+			Text [ x-comment ] = " ";
+		};
+		String 8 // Name of Parameter 4
+		{
+			Text [ de ] = " ";
+			Text [ en-US ] = "A1";
+			Text [ x-comment ] = " ";
+		};
+		String 9 // Description of Parameter 4
+		{
+			Text [ en-US ] = "If TRUE (or 1) or omitted generate A1 style address, otherwise produce R1C1 style address.";
+		Text[ cs ] = "Pokud je hodnota pravdivá (nebo 1) nebo je vynechána, adresy budou ve stylu A1. V opačném případě bude použit styl R1C1.";
+		Text[ de ] = "Wenn TRUE (oder 1) bzw. ausgelassen, A1-Adresse generieren, anderenfalls R1C1-Adresse erstellen.";
+		Text[ es ] = "Si el valor es TRUE (o 1) o se omite, genera una dirección del estilo A1; de lo contrario, genera una dirección del estilo R1C1.";
+		Text[ fr ] = "Si TRUE (ou 1) ou omis, générer une adresse de style A1. Sinon, produire une adresse de style R1C1.";
+		Text[ it ] = "Se impostato su TRUE (o 1) oppure se omesso genera un indirizzo tipo A1, altrimenti genera un indirizzo di tipo R1C1.";
+		Text[ ja ] = "TRUE (1)またはA1スタイルアドレスが作成されていない場合、R1C1スタイルアドレスが作成されます。";
+		Text[ pt-BR ] = "Se VERDADEIRO (ou 1) ou omitido, gerar endereço em estilo A1; caso contrário produzir endereço em estilo R1C1.";
+		Text[ zh-CN ] = "如果为 TRUE（或 1），忽略生成 A1 样式地址，否则生成 R1C1 样式地址。";
+		Text[ zh-TW ] = "如果是傳回 TRUE (或 1) 或是省略就會產生 A1 格式位址，傳回其他值則會產生 R1C1 格式位址。";
+			Text [ x-comment ] = " ";
+		};
+		String 10 // Name of Parameter 5
+		{
+			Text [ de ] = "Tabelle" ;
+			Text [ en-US ] = "sheet" ;
+			Text [ cs ] = "List";
+			Text [ x-comment ] = " ";
+		};
+		String 11 // Description of Parameter 5
+		{
+			Text [ de ] = "Der Tabellenname des Zellbezugs." ;
+			Text [ en-US ] = "The spreadsheet name of the cell reference." ;
+			Text [ cs ] = "Název sešitu odkazující buňky";
+			Text [ x-comment ] = " ";
+		};
+	};
 	 // -=*# Resource for function BEREICHE #*=-
 	Resource SC_OPCODE_AREAS
 	{
@@ -9512,6 +9601,57 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
 			Text [ x-comment ] = " ";
 		};
 	};
+	 // -=*# Resource for function INDIREKT_XL #*=-
+	Resource SC_OPCODE_INDIRECT_XL
+	{
+		String 1 // Description
+		{
+			Text [ de ] = "Bestimmt den Inhalt einer als Bezug in MS Excel (tm) Textform angegebenen Zelle." ;
+			Text [ en-US ] = "Returns the contents of a cell that is referenced in MS Excel (tm) text form." ;
+			Text [ cs ] = "Vrátí obsah buňky na kterou se odkazuje pomocí textové formy MS Excelu (tm).";
+			Text [ x-comment ] = " ";
+		};
+		ExtraData =
+		{
+			ID_FUNCTION_GRP_TABLE;
+			U2S( HID_FUNC_INDIREKT_XL );
+			2;	0;	1;	
+		};
+		String 2 // Name of Parameter 1
+		{
+			Text [ de ] = "Bezug" ;
+			Text [ en-US ] = "ref " ;
+			Text [ x-comment ] = " ";
+		};
+		String 3 // Description of Parameter 1
+		{
+			Text [ de ] = "Die Zelle, deren Inhalt ausgewertet werden soll als Bezug in MS Excel (tm) Textform (z.B. \"Sheet!A1\")." ;
+			Text [ en-US ] = "The cell whose contents are to be evaluated is to be referenced in MS Excel (tm) text form (e.g. \"Sheet!A1\")." ;
+			Text [ cs ] = "Na buňku, jejíž obsah bude vyhodnocován, bude odkazováno ve formátu MS Excelu (tm) (např. \"List!A1\").";
+			Text [ x-comment ] = " ";
+		};
+		String 4 // Name of Parameter 2
+		{
+			Text [ de ] = "'Adressformat'" ;
+			Text [ en-US ] = "Format" ;
+			Text [ cs ] = "Formát";
+			Text [ x-comment ] = " ";
+		};
+		String 5 // Description of Parameter 2
+		{
+			Text [ en-US ] = "What address format to expect.  TRUE for A1, FALSE for R1C1.  Defaults to A1." ;
+		Text[ cs ] = "Jaký formát odkazu je očekáván. TRUE (pravda) pro A1, FALSE (nepravda) pro R1C1. Standardně A1.";
+		Text[ de ] = "Zu erwartendes Adressformat.  TRUE für A1, FALSE für R1C1.  Standardmäßig wird A1 verwendet.";
+		Text[ es ] = "Formato de dirección que se debe esperar. TRUE para A1, FALSE para R1C1. El valor por defecto es A1.";
+		Text[ fr ] = "Quel format d'adresse attendre.  TRUE pour A1, FALSE pour R1C1.  La valeur par défaut est A1.";
+		Text[ it ] = "Formato di indirizzo previsto.  TRUE per A1, FALSE per R1C1.  Il valore predefinito è A1.";
+		Text[ ja ] = "作成されるアドレス形式  TRUEの場合はA1、FALSEの場合はR1C1が作成されます。  デフォルトでは、A1になります。";
+		Text[ pt-BR ] = "Formato do endereço esperado. VERDADEIRO para A1, FALSO para R1C1. Usa A1 por padrão.";
+		Text[ zh-CN ] = "期望何种地址格式。TRUE 代表 A1，FALSE 代表 R1C1。默认值为 A1。";
+		Text[ zh-TW ] = "預期會產生的位址格式。TRUE 會產生 A1 格式，FALSE 會產生 R1C1 格式。預設是產生 A1 格式。";
+			Text [ x-comment ] = " ";
+		};
+	};
 	 // -=*# Resource for function VERWEIS #*=-
 	Resource SC_OPCODE_LOOKUP
 	{
diff -r -u -p sc/source/ui/undo/undotab.cxx sc/source/ui/undo/undotab.cxx
--- sc/source/ui/undo/undotab.cxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/undo/undotab.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -95,6 +95,7 @@ TYPEINIT1(ScUndoPrintRange,		SfxUndoActi
 TYPEINIT1(ScUndoScenarioFlags,	SfxUndoAction);
 TYPEINIT1(ScUndoRenameObject,	SfxUndoAction);
 TYPEINIT1(ScUndoLayoutRTL,		SfxUndoAction);
+TYPEINIT1(ScUndoSetAddressConvention,		SfxUndoAction);
 
 
 // -----------------------------------------------------------------------
@@ -1533,5 +1534,61 @@ String __EXPORT ScUndoLayoutRTL::GetComm
 
 
 
+// -----------------------------------------------------------------------
+//
+//		Set the address convention used for the sheet
+//
+
+ScUndoSetAddressConvention::ScUndoSetAddressConvention( ScDocShell* pShell,
+														ScAddress::Convention eConv ) :
+	ScSimpleUndo( pShell ),
+	eNewConv( eConv )
+{
+	eOldConv = pDocShell->GetDocument()->GetAddressConvention();
+}
+
+__EXPORT ScUndoSetAddressConvention::~ScUndoSetAddressConvention()
+{
+}
+
+void ScUndoSetAddressConvention::DoChange( ScAddress::Convention eConv )
+{
+	pDocShell->SetInUndo( TRUE );
+	ScDocument* pDoc = pDocShell->GetDocument();
+	pDoc->SetAddressConvention( eConv );
+	pDocShell->SetDocumentModified();
+	pDocShell->SetInUndo( FALSE );
+}
+
+void __EXPORT ScUndoSetAddressConvention::Undo()
+{
+	DoChange( eOldConv );
+}
+
+void __EXPORT ScUndoSetAddressConvention::Redo()
+{
+	DoChange( eNewConv );
+}
+
+void __EXPORT ScUndoSetAddressConvention::Repeat(SfxRepeatTarget& rTarget)
+{
+	if (rTarget.ISA(ScTabViewTarget))
+		((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
+			Execute( FID_TAB_USE_R1C1, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+}
+
+BOOL __EXPORT ScUndoSetAddressConvention::CanRepeat(SfxRepeatTarget& rTarget) const
+{
+	return (rTarget.ISA(ScTabViewTarget));
+}
+
+String __EXPORT ScUndoSetAddressConvention::GetComment() const
+{
+	return ScGlobal::GetRscString( STR_UNDO_TAB_R1C1 );
+}
+
+
+
+
 
 
diff -r -u -p sc/source/ui/unoobj/cellsuno.cxx sc/source/ui/unoobj/cellsuno.cxx
--- sc/source/ui/unoobj/cellsuno.cxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/unoobj/cellsuno.cxx	2006-08-24 22:23:19.000000000 -0400
@@ -4914,9 +4914,16 @@ uno::Reference<table::XCellRange> SAL_CA
 	return NULL;
 }
 
+
 uno::Reference<table::XCellRange> SAL_CALL ScCellRangeObj::getCellRangeByName(
 						const rtl::OUString& aName ) throw(uno::RuntimeException)
 {
+	return getCellRangeByName( aName, ScAddress::detailsOOOa1 ); 
+}
+
+uno::Reference<table::XCellRange>  ScCellRangeObj::getCellRangeByName(
+						const rtl::OUString& aName, const ScAddress::Details& rDetails  ) throw(uno::RuntimeException)
+{
 	//	name refers to the whole document (with the range's table as default),
 	//	valid only if the range is within this range
 
@@ -4930,7 +4937,7 @@ uno::Reference<table::XCellRange> SAL_CA
 		ScRange aCellRange;
 		BOOL bFound = FALSE;
 		String aString(aName);
-		USHORT nParse = aCellRange.ParseAny( aString, pDoc );
+		USHORT nParse = aCellRange.ParseAny( aString, pDoc, rDetails );
 		if ( nParse & SCA_VALID )
 		{
 			if ( !(nParse & SCA_TAB_3D) )	// keine Tabelle angegeben -> auf dieser Tabelle
diff -r -u -p sc/source/ui/view/colrowba.cxx sc/source/ui/view/colrowba.cxx
--- sc/source/ui/view/colrowba.cxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/view/colrowba.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -95,6 +95,11 @@ ScColBar::~ScColBar()
 {
 }
 
+inline BOOL ScColBar::UseNumericHeader() const
+{
+    return pViewData->GetDocument()->GetAddressConvention() == ScAddress::CONV_XL_R1C1;
+}
+
 SCCOLROW ScColBar::GetPos()
 {
 	return pViewData->GetPosX(eWhich);
@@ -112,7 +117,9 @@ USHORT ScColBar::GetEntrySize( SCCOLROW 
 
 String ScColBar::GetEntryText( SCCOLROW nEntryNo )
 {
-	return ColToAlpha( static_cast<SCCOL>(nEntryNo) );
+	return UseNumericHeader()
+	    ? String::CreateFromInt32( nEntryNo + 1 )
+	    : ColToAlpha( static_cast<SCCOL>(nEntryNo) );
 }
 
 void ScColBar::SetEntrySize( SCCOLROW nPos, USHORT nNewSize )
diff -r -u -p sc/source/ui/view/tabvwshf.cxx sc/source/ui/view/tabvwshf.cxx
--- sc/source/ui/view/tabvwshf.cxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/view/tabvwshf.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -687,6 +687,17 @@ void ScTabViewShell::ExecuteTable( SfxRe
 			}
 			break;
 
+		case FID_TAB_USE_R1C1:
+			{
+				ScDocFunc aFunc( *pViewData->GetDocShell() );
+				const ScAddress::Convention eConv =  
+					(pDoc->GetAddressConvention() == ScAddress::CONV_OOO)
+						? ScAddress::CONV_XL_R1C1 : ScAddress::CONV_OOO ;
+
+				aFunc.SetAddressConvention( eConv );
+			}
+			break;
+
 		default:
 			DBG_ERROR("Unbekannte Message bei ViewShell");
 			break;
@@ -806,6 +817,13 @@ void ScTabViewShell::GetStateTable( SfxI
 						rSet.Put( SfxBoolItem( nWhich, pDoc->IsLayoutRTL( nTab ) ) );
 				}
 				break;
+
+			case FID_TAB_USE_R1C1:
+				{
+					const ScAddress::Convention eConv =  pDoc->GetAddressConvention();
+					rSet.Put( SfxBoolItem( nWhich, eConv == ScAddress::CONV_XL_R1C1 ) );
+				}
+				break;
 		}
 		nWhich = aIter.NextWhich();
 	}
diff -r -u -p sc/source/ui/view/viewfunc.cxx sc/source/ui/view/viewfunc.cxx
--- sc/source/ui/view/viewfunc.cxx	2006-09-05 23:35:41.000000000 -0400
+++ sc/source/ui/view/viewfunc.cxx	2006-08-24 10:45:05.000000000 -0400
@@ -834,7 +834,7 @@ void ScViewFunc::EnterMatrix( const Stri
 		SCCOL nCol = pData->GetCurX();
 		SCROW nRow = pData->GetCurY();
 		SCTAB nTab = pData->GetTabNo();
-		ScFormulaCell aFormCell( pDoc, ScAddress(nCol,nRow,nTab), rString, MM_FORMULA );
+		ScFormulaCell aFormCell( pDoc, ScAddress(nCol,nRow,nTab), rString, ScAddress::CONV_UNSPECIFIED, MM_FORMULA );
 
         SCSIZE nSizeX;
         SCSIZE nSizeY;
